Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Questions on Backbone.js with Handlebars.js

My backbone.js app with Handelbars does the following.

  1. setup a model, its collection, view and router.
  2. at the start, get a list of articles from the server and render it using the view via Handlebars.js template.

The code is below.

    (function ($) 
    {
      // model for each article
      var Article = Backbone.Model.extend({});

      // collection for articles
      var ArticleCollection = Backbone.Collection.extend({
        model: Article
      });

      // view for listing articles
      var ArticleListView = Backbone.View.extend({
        el: $('#main'),
        render: function(){
          var js = JSON.parse(JSON.stringify(this.model.toJSON()));
          var template = Handlebars.compile($("#articles_hb").html());
          $(this.el).html(template(js[0]));
          return this;  
        }
      });

      // main app
      var ArticleApp = Backbone.Router.extend({
        _index: null,
        _articles: null,

        // setup routes
        routes: {
          "" : "index"
        },

        index: function() {
          this._index.render();
        },

        initialize: function() {
          var ws = this;
          if( this._index == null ) {
            $.get('blogs/articles', function(data) {
              var rep_data = JSON.parse(data);
              ws._articles = new ArticleCollection(rep_data);
              ws._index = new ArticleListView({model: ws._articles});
              Backbone.history.loadUrl();
          });               
          return this;
        }
        return this;
      }
    });

    articleApp = new ArticleApp();
  })(jQuery);

Handlebars.js template is

<script id="articles_hb" type="text/x-handlebars-template">
  {{#articles}}
    {{title}}
  {{/articles}}
</script>

The above code works fine and it prints article titles. However, my question is

  1. When passing context to Handlebars.js template, I am currently doing $(this.el).html(template(js[0])). Is this the right way? When I do just "js" instead of js[0], the JSON object has leading and ending square brackets. Hence it recognizes as a array object of JSON object. So I had to js[0]. But I feel like it isn't a proper solution.

  2. When I first create the "View", I am creating it like below.

    ws._index = new ArticleListView({model: ws._articles});

But in my case, I should do

ws._index = new ArticleListView({collection: ws._articles});

Shouldn't I? (I was following a tutorial btw). Or does this matter? I tried both, and it didn't seem to make much difference.

Thanks in advance.

like image 882
ericbae Avatar asked Sep 08 '11 08:09

ericbae


1 Answers

It seems like you are creating a view for a collection so you should initialize your view using collection instead of model.

As far as handlebars, I haven't used it a lot but I think you want to do something like this:

var ArticleListView = Backbone.View.extend({
    el: $('#main'),
    render: function(){
      var js = this.collection.toJSON();
      var template = Handlebars.compile($("#articles_hb").html());
      $(this.el).html(template({articles: js}));
      return this;  
    }
  });

and then use something like this for the template

  {{#each articles}}
    {{this.title}}
  {{/each}}

p.s. the line JSON.parse(JSON.stringify(this.model.toJSON())) is equivalent to this.model.toJSON()

Hope this helps

like image 76
timDunham Avatar answered Oct 20 '22 03:10

timDunham