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