Trunk - Why doesn't the collector fire a model event?

I am curious to know why a core network reset does not trigger a model event. However, it seems logical to trigger a model event when the model is physically removed from the collection.

Is it intentional or am I missing something? If the spine does not do this kind of thing, it is good practice to delegate such events.

Why doesn't the server fire a model event when its collection fails?

var TicketModel = Backbone.Model.extend({ defaults: { name: 'crafty', email: ' dwq@dwqcqw.com ' }, initialize: function(){ this.on("all", function(event){ console.log(event) }); } }); var TicketCollection = Backbone.Collection.extend({ model: TicketModel, }); var tickets = new TicketCollection([ { name: 'halldwq' }, { name: 'dascwq' }, { name: 'dsacwqe' } ]); tickets.reset(); 
+7
source share
2 answers

The method of overriding the database can cause pain when upgrading to a different version.

The trunk stores an array of models until reset in options.previousModels, so just listen for the reset event and fire the delete event on these previous models:

 collection.on('reset', function(col, opts){ _.each(opts.previousModels, function(model){ model.trigger('remove'); }); }); 

That would do the trick.

+16
source

This is the main reset function:

 reset: function(models, options) { models || (models = []); options || (options = {}); for (var i = 0, l = this.models.length; i < l; i++) { this._removeReference(this.models[i]); } this._reset(); this.add(models, _.extend({silent: true}, options)); if (!options.silent) this.trigger('reset', this, options); return this; }, 

We can ignore the last 3 lines because you are not supplying any models to the reset function. Also, let the first 2 lines be ignored. Therefore, we first look at the models in this collection and call the collection method _removeReference(model) , it looks like this:

 _removeReference: function(model) { if (this == model.collection) { delete model.collection; } model.off('all', this._onModelEvent, this); }, 

What happens here is that we completely remove the collection property from the model object, and also remove the binding to these model events. Then we call the collection of _reset() functions, which looks like this:

 _reset: function(options) { this.length = 0; this.models = []; this._byId = {}; this._byCid = {}; }, 

It simply removes any link to any models that have ever been in the collection.

What can we make of this? Well, the collection of reset function in Backbone basically just bypasses all the official channels for deleting models and does it all in hidden silence, without causing any other events than reset . So, do you want to fire the remove model event for each model removed from the collection during reset? Easy! Just replace the Backbone.Collection reset function as follows:

 var Collection = Backbone.Collection.extend({ reset: function(models, options) { models || (models = []); options || (options = {}); for (var i = 0, l = this.models.length; i < l; i++) { this._removeReference(this.models[i]); // trigger the remove event for the model manually this.models[i].trigger('remove', this.models[i], this); } this._reset(); this.add(models, _.extend({silent: true}, options)); if (!options.silent) this.trigger('reset', this, options); return this; } }); 

Hope this helps!

+16
source

All Articles