admin管理员组文章数量:1187846
I'm curious to find out why resetting a backbone collection doesn't fire a model event. However, it seems only logical to fire a model event when a model is physically being removed from a collection.
Is this intentional or am I missing something? If backbone doesn't do this sort of thing what's a good practice for delegating events like so.
Why does backbone not trigger a model event when its collection resets?
var TicketModel = Backbone.Model.extend({
defaults: {
name: 'crafty',
email: '[email protected]'
},
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();
I'm curious to find out why resetting a backbone collection doesn't fire a model event. However, it seems only logical to fire a model event when a model is physically being removed from a collection.
Is this intentional or am I missing something? If backbone doesn't do this sort of thing what's a good practice for delegating events like so.
Why does backbone not trigger a model event when its collection resets?
var TicketModel = Backbone.Model.extend({
defaults: {
name: 'crafty',
email: '[email protected]'
},
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();
Share
Improve this question
edited Aug 2, 2012 at 11:49
Rimian
38.4k17 gold badges124 silver badges119 bronze badges
asked Aug 2, 2012 at 9:34
Julian Krispel-SamselJulian Krispel-Samsel
7,7244 gold badges34 silver badges41 bronze badges
1
- fair enough, if that makes it clearer, thanks rimian – Julian Krispel-Samsel Commented Aug 2, 2012 at 12:04
2 Answers
Reset to default 16This is the backbone 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 don't supply any models to the reset-function. Also let's ignore the first 2 lines as well. So first we loop through the models in this collection and call the collection's _removeReference(model)
method, 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're removing the collection-property from the model object altogether and also remove the binding to this model's events. Next up we call the collection's _reset()
-function, that looks like this:
_reset: function(options) {
this.length = 0;
this.models = [];
this._byId = {};
this._byCid = {};
},
It just outright removes any reference to any models the collection has ever had.
What can we make from this? Well the collection reset
-function in Backbone basically just circumvents all the official channels of removing models and does it all in hush hush secrecy, causing no other events than reset
to be fired. So you want to fire the model's remove
event for every model removed from a collection during reset? Easy! Just overwrite Backbone.Collection's reset-function like this:
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!
Overriding Backbone method can cause pain when updating to another version.
Backbone stores an array of the models before the reset in options.previousModels, so just listen to the reset event and trigger a 'remove' event on those previous models:
collection.on('reset', function(col, opts){
_.each(opts.previousModels, function(model){
model.trigger('remove');
});
});
That'd do the trick.
本文标签: javascriptBackboneWhy doesn39t a collectionreset trigger a model eventStack Overflow
版权声明:本文标题:javascript - Backbone - Why doesn't a collection.reset trigger a model event? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738359783a2080515.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论