8

バックボーンコレクションをリセットしてもモデルイベントが発生しない理由を知りたいです。ただし、モデルがコレクションから物理的に削除されているときにモデルイベントを発生させるのは論理的であるように思われます。

これは意図的なものですか、それとも何かが足りないのですか?バックボーンがこの種のことを行わない場合、そのようなイベントを委任するための良い習慣は何ですか。

コレクションがリセットされたときにバックボーンがモデルイベントをトリガーしないのはなぜですか?

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();
4

2 に答える 2

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行は無視できます。また、最初の2行も無視しましょう。したがって、最初にこのコレクションのモデルをループして、コレクションの_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以外のイベントを引き起こしません。では、リセット中にコレクションから削除されたすべてのモデルに対してresetモデルのイベントを発生させたいですか?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;
  }
});

お役に立てれば!

于 2012-08-02T09:59:35.610 に答える
16

バックボーンメソッドをオーバーライドすると、別のバージョンに更新するときに問題が発生する可能性があります。

バックボーンは、リセット前にモデルの配列をoptions.previousModelsに格納するため、リセットイベントをリッスンし、それらの以前のモデルで「削除」イベントをトリガーするだけです。

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

それでうまくいくでしょう。

于 2013-02-08T17:19:28.137 に答える