Reputation: 4059
The model collection is not issuing a 'sync' event when a model is destroyed. the documentation seems to say the opposite. here is my code snippet:
var MyModel = Backbone.Model.extend({ id: 1, val: "foo" });
var MyCollection = Backbone.Collection.extend({ model: MyModel, url: '/api/models' });
var myCollection = new MyCollection();
myCollection.on('sync', function () { console.log('synced!'); });
myCollection.on('remove', function () { console.log('removed!'); });
myCollection.fetch(); // => outputs synced!
// .. wait for collection to load
myCollection.at(0).destroy(); // => outputs removed! but *NOT* synced!
If I understand well, the doc says the 'destroy' event should bubble up to the collection and issue a 'sync' event. Should the collection in the code above issue a 'sync' event or not?
Upvotes: 3
Views: 2918
Reputation: 4059
The 'sync' event is triggered on the destroyed object after being removed from the collection. This is why the collection doesn't fire a 'sync' event. The collection relays the 'destroy' event though.
Upvotes: 7
Reputation: 5060
EDIT: 'sync' is triggered on the model after it is removed from the collection, even if wait:true
option is used.
Here is the code from Backbone, which triggers the model events on the collection.
// Internal method called every time a model in the set fires an event.
// Sets need to update their indexes when models change ids. All other
// events simply proxy through. "add" and "remove" events that originate
// in other collections are ignored.
_onModelEvent: function(event, model, collection, options) {
if ((event === 'add' || event === 'remove') && collection !== this) return;
if (event === 'destroy') this.remove(model, options);
if (model && event === 'change:' + model.idAttribute) {
delete this._byId[model.previous(model.idAttribute)];
if (model.id != null) this._byId[model.id] = model;
}
this.trigger.apply(this, arguments);
},
Your problem is most likely because the 'sync' event is not triggered on the model (and then triggered on the collection) due to an error in during the sync.
From the Backbone source, you can see that 'sync' is triggered when the request succeeds, so maybe you can debug that and see if the success callback in sync
is hit?
var success = options.success;
options.success = function(resp) {
if (success) success(model, resp, options);
model.trigger('sync', model, resp, options); // breakpoint here.
};
Can you put a breakpoint in there and see if the event is triggered? I assume it will not hit this line.
Also try using an error callback:
myCollection.at(0).destroy({
error: function(model, xhr, options){
console.log(model); // this will probably get hit
}
});
Upvotes: 4