繁体   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