I am a Backbone.js n00b and trying to get my head around it. I know how to render a model using a view and the built-in underscore.js templating engine. Now I\'m trying to r
It is also worth noting there are additional complexities that quickly rear their heads when rendering a collection in a view. For instance, the view generally needs to be re-rendered when models are added or removed from the collection. It isn't rocket science to implement your own solution, but it is probably worth looking into existing solutions since there are quite a few tried and tested ones out there.
Backbone.CollectionView is a robust collection view class that handles selecting models in response to mouse clicks, reordering the collection based on drag and drop, filtering visible models, etc.
Several popular frameworks built on top of backbone also provide simple collection view classes, like Backbone.Marionette, Chaplin, and Layout Manager.
Even though Backbone itself does not provide any structure for rendering a collection, it is a non-trivial problem and lots of people have different opinions on how it should be done. Luckily it is such a common need that there are quite a few good options already in the eco system.
The problem is that when you define ContinentsView, the template is evaluated and it uses $('#continents-template')
- but the DOM is not ready yet, so it does not find the template.
To solve it, simply move the template assignment in the initialize function:
ContinentsView = Backbone.View.extend({
el: '#continents',
initialize: function() {
this.template = _.template($('#continents-template').html());
}
...
Regarding collections, yes, they are grouping objects, specifically sets of models.
You should make the code so the models (and collections) do NOT know about the views, only the views know about models.
ContinentModel = Backbone.Model.extend({});
ContinentsCollection = Backbone.Collection.extend({
model: ContinentModel,
// no reference to any view here
});
ContinentsView = Backbone.View.extend({
el: '#continents',
initialize: function() {
this.template = _.template($('#continents-template').html());
// in the view, listen for events on the model / collection
this.collection.bind("reset", this.render, this);
},
render: function() {
var renderedContent = this.template(this.collection.toJSON());
$(this.el).html(renderedContent);
return this;
}
});
$(function() {
var continentsCollection = new ContinentsCollection();
continentsCollection.reset([{name: "Asia"}, {name: "Africa"}]);
// initialize the view and pass the collection
var continentsView = new ContinentsView({collection: continentsCollection});
});