Questions on Backbone.js with Handlebars.js
My backbone.js app with Handelbars does the following.
- setup a model, its collection, view and router.
- 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开发者_JS百科-handlebars-template">
{{#articles}}
{{title}}
{{/articles}}
</script>
The above code works fine and it prints article titles. However, my question is
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.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.
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
var ArticleListView = Backbone.View.extend({
initialize: function(){
this.template = Handlebars.compile($('#articles_hb').html());
},
render: function(){
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
/////////////////////////////////////
ws._index = new ArticleListView({model: ws._articles});
精彩评论