Reputation: 1115
In spite of the many questions/answers on this same topic on StackOverflow and elsewhere, I still don't understand how to proceed. I would like a change in my collection to trigger the render function in my view. View has a collection, not a model -- so the many examples I see for model.bind are not applicable. Apparently collection.bind is not a legitimate binding. Here's my view code. What should I add in initialize so that when orderedPrefs (collection) has a change, the view's render function is called?
headerView = Backbone.View.extend({
el: $('#' + targetdiv),
collection: orderedPrefs,
events: {
"click .scheduleheader": "clicked" // dependency here on scheduler.js class naming .scheduleheader
},
initialize: function () {
_.bindAll(this, "render");
},
render: function () {
alert('render!!');
},
..... .....
Upvotes: 2
Views: 930
Reputation: 1097
These should work inside the initialize function:
this.collection.on("add", this.render);
this.collection.on("remove", this.render);
this.collection.on("reset", this.render);
If they don't, you have a problem with the collection attached to the view. You should not use global "orderedPrefs".
Backbone docs state:
When creating a new View, the options you pass are attached to the view as this.options, for future reference. There are several special options that, if passed, will be attached directly to the view: model, collection, el, id, className, tagName and attributes.
When instantiating your view, you need to pass the collection like this:
new headerView({ collection: orderedPrefs });
If you want to track changes in the collection models, you should do it in a different view:
var ModelView = Backbone.View.extend({
initialize: function() {
_.bindAll(this, "render");
this.render();
this.model.on("change",this.render);
},
render: function() {
$(this.el).html("model view markup"); // you should use templating
return this;
}
});
var headerView = Backbone.View.extend({
el: $('#' + targetdiv),
initialize: function () {
_.bindAll(this, "render");
this.collection.on("add", this.render);
this.collection.on("remove", this.render);
this.collection.on("reset", this.render);
},
render: function () {
var self = this;
this.collection.each(function(collectionModel){
var view = new ModelView({ model : collectionModel });
$(self.el).append(view.el);
});
}
});
Upvotes: 3
Reputation: 102743
You can bind using collection.on
to the "add" and "remove" events. See the documentation under Add for an example of usage.
this.collection.on("add", this.render);
If you're using Backbone version 0.9.0 or newer, then you can bind multiple events in the same statement:
this.collection.on("add remove", this.render);
Note also that "bind" should work the same as "on":
bind and unbind have been renamed to on and off for clarity, following jQuery's lead. The old names are also still supported.
Upvotes: 1