7

我很想知道为什么重置骨干网集合不会触发模型事件。然而,当一个模型被物理地从集合中移除时,触发模型事件似乎是合乎逻辑的。骨干 - 为什么没有一个collection.reset触发模型事件?

这是故意的还是我错过了什么?如果骨干不这样做,那么像这样委托事件是一种好的做法。

为什么主干在集合重置时不会触发模型事件?

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(); 
+0

够公平的,如果这使得它更清晰,谢谢rimian – nimrod 2012-08-02 12:04:23

回答

16

重写Backbone方法会在更新到其他版本时导致疼痛。

骨干存储在options.previousModels复位之前的车型阵列,所以只听重置事件和触发那些以前的型号“删除”事件:

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

那会做招。

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条线路,因为你不提供任何模型复位功能。还让我们忽略前两行。通过这个集合中的模型所以我们首先循环,并呼吁集合的_removeReference(model)方法,它看起来像这样:

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

这里会发生什么事是,我们干脆也去除模型对象的集合,属性中删除绑定到这个模型的事件。接下来,我们称之为集合的_reset()功能全,看起来像这样:

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

它只是彻底消除了收集有过任何车型任何引用。

我们能做些什么?那么在Backbone中的功能集合reset基本上只是规避了所有删除模型的官方渠道,并且以嘘声保密的方式执行,导致除了被触发的事件外,没有其他事件发生。因此,您想要在重置期间为从集合中移除的每个模型启动模型的remove事件?简单!刚刚覆盖Backbone.Collection的复位功能是这样的:

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; 
    } 
}); 

希望这有助于!

+0

非常彻底的答案。还可以愉快地阅读!非常感谢! – nimrod 2012-08-02 10:18:05

+0

没问题,通过源代码找到这样的问题的解决方案总是一个很好的学习经验! – jakee 2012-08-02 10:19:16

+0

我不知道它背后的推理是什么。一个模型的“删除”事件冒泡到集合中,为什么不相反呢? – nimrod 2012-08-02 10:30:00