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

それがもっと分かりやすい場合は、感謝リーマン – nimrod

答えて

16

バックボーンの方法を無効にすると、別のバージョンに更新するときに痛みを引き起こす可能性があります。

バックボーンは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行を無視することができます。また、最初の2行も無視してみましょう。このコレクションのモデルを通してだから、まずはループとコレクションの_removeReference(model)メソッドを呼び出し、それは次のようになります。

_removeReference: function(model) { 
    if (this == model.collection) { 
    delete model.collection; 
    } 
    model.off('all', this._onModelEvent, this); 
}, 

ここに何が起こる我々は完全にモデルオブジェクトからコレクション・プロパティを削除しても削除しているということですこのモデルのイベントへのバインディング次は、私たちはこのようになりますコレクションの_reset() -functionを呼び出す:

_reset: function(options) { 
    this.length = 0; 
    this.models = []; 
    this._byId = {}; 
    this._byCid = {}; 
}, 

それはちょうどあからさまなコレクションが今まで持っていた任意のモデルへの参照を削除します。

私たちはこれで何ができますか?まあ、バックボーンのコレクションresetは、基本的にはモデルを削除する公式チャンネルをすべて迂回し、それはすべてハッシュ秘密で行い、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

+0

問題はありませんが、このような質問の解決策を見つけるためには、ソースコードを辿るのは常に素晴らしい学習体験です! – jakee

+0

私はそれの背後にある推論が何であるのだろうか。モデルの「削除」イベントはコレクションまで泡立つので、それ以外の理由は何故ですか? – nimrod

関連する問題