簡體   English   中英

Backbone - 為什么collection.reset不會觸發模型事件?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM