Reputation: 1250
So i got this sub model associate to 1 list item of my view, when I edit this model, the view is re rendered correctly.
But I also got other things parent do when the complete list model change, and the change event is not firing at the aprent level which is weird,
if I manually fire model.change() I see the content updated from the submodel (meaning the parent model as effectively changed).
Is there an automatic way to propagate the change event to the parent model?
Upvotes: 1
Views: 4225
Reputation: 336
I like JohnnyO's solution, and I've used his solution to make a generic "SuperModel" class in my application. Here is the Coffeescript version of this class, which allows the registration of child models with a parent and automatically propagates all events:
class Model.SuperModel extends Backbone.Model
includeChild: (id, model) ->
@set id, model
@listenTo model, 'all', @trigger
And that's it. Using it is easy:
parent = new Model.SuperModel()
parent.includeChild('child', new Backbone.Model())
view = new Backbone.View()
view.listenTo(parent, 'change', -> console.log "parent changed!")
parent.get('child').set('foo', 'bar')
This will print out "parent changed", as you would expect.
Upvotes: 1
Reputation: 57502
Is your "parent" the collection in which the sub-model belongs? If so, the collection will receive a change notification whenever an attributes of the sub-model changes. Here's an example that demonstrates the model / collection change event:
var Product = Backbone.Model.extend({});
var Products = Backbone.Collection.extend({
model: Product
});
var ProductsView = Backbone.View.extend({
initialize: function () {
this.collection.bind('change', this.onProductChange, this);
},
onProductChange: function (product) {
console.log('product with ID ' + product.get('id') + ' changed to ' + product.get('name'));
}
});
var products = new Products([{ id: 1, name: 'Book' }, { id: 2, name: 'Toy' }, { id: 3, name: 'Shirt'}]);
new ProductsView({collection:products});
products.get(1).set({ name: 'TV' }); // console: product with ID 1 changed to TV
On the other hand, if your "parent" is not a collection of your sub-model and there's simply a parent/child relationship, then Backbone has no way to know about the relationship, so you will need to trigger the change event on the parent whenever a child changes. For example:
var Parent = Backbone.Model.extend({
includeChild: function (child) {
child.bind('change', this.onChildChange, this);
},
onChildChange: function (child) {
console.log('Child with name ' + child.get('name') + ' changed.');
}
});
var Child = Backbone.Model.extend({});
var parent = new Parent();
var child = new Child({ name: 'Bob', parent: parent });
parent.includeChild(child);
child.set({name: 'Joe'}); // console: Child with name Joe changed.
Here's a complete list of Backbone events: http://documentcloud.github.com/backbone/#FAQ-events
Upvotes: 4