Collection
が内部の混乱状態に陥る原因となる、バックボーンアプリケーションの一連の手順を理解できる最も簡単な再現については、以下をご覧ください。
作業コピーは、このJSFiddleにあります。
それが示すのは、 collection
remove()
-ed Model
内部( _byId
)参照を保持するremove()
Model
です。 そのModel
はcollection.models
一部ではなくなりましたが、(以前の) id
介して取得できます。
var
MyView = Backbone.View.extend( {
initialize: function () {
this.model = new Backbone.Model( {
id: 'foo'
, foo: 'bar'
} );
this.collection = new Backbone.Collection( this.model );
this.listenTo( this.model, 'change:id', function ( model, id ) {
if ( id == null ) {
this.collection.remove( model );
}
} );
this.model.unset( 'id' );
$('#models' ).val( JSON.stringify( this.collection.models ));
$('#_byId' ).val( JSON.stringify( this.collection._byId ));
$('#get-foo').val( JSON.stringify( this.collection.get( 'foo' )));
}
})
, foo = new MyView()
;
うーん、面白い。 モデルをコレクションに追加するとき、__ byId_は、model.idとmodel.cidという2つのプロパティを追加します。これらは、モデルへの参照です。 1134行で発行、 id === undefinedですが、__ byId_にはmodel.id --_ ' foo'_が含まれています。
model.idをvalue == nullに変更する場合、コレクションには特別なロジックがありません。行1183を確認してください。
また、 unsetを変更して_null_または_undefined_を設定することもできます。 this.model.set( 'id'、null);
PS:モデルIDをnullまたは未定義に設定する必要はないと思います。これはアンチパターンです。
はい—決してこれを行うべきではありませんが、それでもバグです。
id
が値からnull
に変更される場合delete this._byId[id]
なるようにして、これを修正する必要があります。
イベントを使用せずにコレクションからモデルを削除すると、期待どおりに機能します。 問題は_onModelEvent
あり、この場合に送信される実際のイベント名がchange:id
場合、イベントの名前がchange
であるかどうかをチェックします。
最も参考になるコメント
はい—決してこれを行うべきではありませんが、それでもバグです。
id
が値からnull
に変更される場合delete this._byId[id]
なるようにして、これを修正する必要があります。