我很想知道为什么重置骨干集合不会触发模型事件。但是,在从集合中物理移除模型时触发模型事件似乎是合乎逻辑的。
这是故意还是我错过了什么?如果骨干不做这种事情,那么委托事件就是一个很好的做法。
为什么骨干在其集合重置时不会触发模型事件?
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();
答案 0 :(得分:16)
这是主干复位功能:
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;
},
我们可以忽略最后3行,因为你没有为reset-function提供任何模型。我们也要忽略前两行。首先,我们遍历此集合中的模型并调用集合的_removeReference(model)
方法,它看起来像这样:
_removeReference: function(model) {
if (this == model.collection) {
delete model.collection;
}
model.off('all', this._onModelEvent, this);
},
这里发生的是我们从模型对象中完全删除了collection-property,并删除了对该模型事件的绑定。接下来我们调用集合的_reset()
- 函数,如下所示:
_reset: function(options) {
this.length = 0;
this.models = [];
this._byId = {};
this._byCid = {};
},
它直接删除了对该系列曾经拥有的任何模型的任何引用。
我们可以从中做出什么? Backbone中的集合reset
- 函数基本上只是绕过了删除模型的所有官方渠道,并且在嘘声保密的情况下完成所有操作,导致除了reset
之外没有其他事件被触发。因此,您希望在重置期间为从集合中删除的每个模型触发模型的remove
事件?简单!只需覆盖Backbone.Collection的reset-function,如下所示:
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;
}
});
希望这有帮助!
答案 1 :(得分:16)
在更新到另一个版本时,覆盖Backbone方法会导致痛苦。
Backbone在options.previousModels中重置之前存储一组模型,所以只需听取重置事件并在之前的模型上触发'remove'事件:
collection.on('reset', function(col, opts){
_.each(opts.previousModels, function(model){
model.trigger('remove');
});
});
这就是诀窍。