Search code examples
javascriptbackbone.jshandlebars.js

Backbone + Handlebars


I am new to backbone and handlebars and trying to emulate a simple scenario. I have two htm pages:

index.htm:

<div id="home">

  <h1 align="center">Music Paradise</h1>
  <div id="navigation" align="center">
    <p align="center">Search for bands of your choice</p>
    <a href="#/SearchBands">Search Bands</a>
    <p align="center">Search for concerts of your choice</p>
    <a href="#/SearchConcerts">Search Concerts</a> 
  </div> 
</div>

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script type="text/javascript" src="../js/backbone.js"></script>
<script type="text/javascript" src="../js/route.js"></script>

A router page:

var BandView = Backbone.View.extend({
      template: Handlebars.compile( $("#SearchBands-template").html() ),      
      initialize: function () {
          this.render();
      },

      render: function () {
          this.$el.html(this.template({greeting:"Welcome to Search Bands Feature!"}));

      }
  });


var ConcertView = Backbone.View.extend({
      template: Handlebars.compile( $("#SearchBands-template").html() ),      
      initialize: function () {
          this.render();
      },
      render: function () {
         this.$el.html(this.template({content:"Welcome to Search Concerts Feature!"}));

      }
    });


  var AppRouter = Backbone.Router.extend({
      routes: {          
          'SearchBands': 'bandRoute',
          'SearchConcerts': 'concertRoute',          
      },
      bandRoute: function () {
          var bandView = new BandView();          
          $("#data").html(bandView.el);
      },
      concertRoute: function () {
          var concertView = new ConcertView();          
          $("#data").html(concertView.el);
      }
  });

  var appRouter = new AppRouter();
  Backbone.history.start();

and the third htm page where the results should be routed to.

searchBands.htm

<div id="home">

  <h1 align="center">Music Paradise</h1>

<div id="data">
</div>

  <script type="text/template" id="SearchBands-template">
      <h1>Please Search Bands</h1>
     {{ greeting }}
  </script>



  <script type="text/template" id="SearchConcerts-template">
      <h1>Please Search Concerts</h1>
      {{ content }}
  </script>


</div>

I am getting the following error: handlebars.min.js:27 Uncaught Error: You must pass a string or Handlebars AST to Handlebars.compile. You passed undefined.

I guess this is due to route.js still doesn't know about searchBands.htm and somehow i need to load searchBands.htm before.

Thanks.


Solution

  • Backbone and its hash based routing you're trying to use is designed for single page applications.

    Your <script> tags containing templates should be available in index.html itself before your application script runs for jQuery to find it via id selector.

    If you want to keep your templates in different HTML files, then you should load them using AJAX somehow and pass them to handlebars. How to do this depends on the broader app structure, for example if you're using RequireJS you can use its text plugin or you can use the load method of jQuery.