![](/img/trans.png)
[英]Backbone Collection.reset() doesn't work on extended Collections
[英]Backbone - Why doesn't a collection.reset trigger a model event?
我很想知道為什么重置骨干集合不會觸發模型事件。 但是,在從集合中物理移除模型時觸發模型事件似乎是合乎邏輯的。
這是故意還是我錯過了什么? 如果骨干不做這種事情,那么委托事件就是一個很好的做法。
為什么骨干在其集合重置時不會觸發模型事件?
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();
這是骨干重置功能:
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
的每個模型觸發模型的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;
}
});
希望這可以幫助!
更新到另一個版本時,重寫Backbone方法會導致痛苦。
Backbone在options.previousModels中重置之前存儲了一組模型,因此只需監聽reset事件並在之前的模型上觸發'remove'事件:
collection.on('reset', function(col, opts){
_.each(opts.previousModels, function(model){
model.trigger('remove');
});
});
那就是訣竅。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.