Reputation: 15209
I have been using Backbone on a new project and so far have loved it, but I have come to a blocker that I can't seem to get around.
Without trying to explain my whole domain model, I have found that when you save a model, the response comes back from the server and gets parsed again, creating new sub objects and therefore breaking and event bindings I had previously put on the object.
For instance, if I save ContentCollection
(its a Backbone.Model not a collection) when it comes back from the server, the response gets parsed and creates a new Collection in this.contentItems
, which breaks all the binding I had on this.contentItems
. Is there any way to get around this? Tell backbone not to parse the response somehow? Grab the bindings off the original list, and then re-attach them to the new list?
App.ContentCollection = Backbone.Model.extend({
urlRoot: '/collection',
initialize: function() {
},
parse: function(resp, xhr) {
this.contentItems = new App.ContentList(resp.items)
this.subscriptions = new App.SubscriptionList(resp.subscriptions)
return resp
},
remove: function(model){
this.contentItems.remove(model)
this.save({'removeContentId':model.attributes.id})
},
setPrimaryContent: function(model){
this.save({'setPrimaryContent':model.attributes.id})
}
})
Has anyone run into this before?
Upvotes: 2
Views: 263
Reputation: 55678
I think the issue here is the way you're using the parse()
method. Backbone just expects this method to take a server response and return a hash of attributes - not to change the object in any way. So Backbone calls this.parse()
within save()
, not expecting there to be any side-effects - but the way you've overridden .parse()
, you're changing the model when the function is called.
The way I've dealt with this use case in the past is to initialize the collections when you first call fetch()
, something like:
App.ContentCollection = Backbone.Model.extend({
initialize: function() {
this.bind('change', initCollections, this);
},
initCollections: function() {
this.contentItems = new App.ContentList(resp.items);
this.subscriptions = new App.SubscriptionList(resp.subscriptions);
// now you probably want to unbind it,
// so it only gets called once
this.unbind('change', initCollections, this)
},
// etc
});
Upvotes: 3