Silakan temukan di bawah ini tentang reproduksi terpendek yang dapat saya pahami dari urutan langkah-langkah dalam aplikasi Backbone yang menyebabkan Collection
mengalami kebingungan internal.
Salinan kerja dapat ditemukan di JSFiddle ini.
Apa yang ditunjukkannya adalah collection
menyimpan referensi internal ( _byId
) ke remove()
-ed Model
. Model
itu bukan lagi bagian dari collection.models
, namun masih dapat diambil melalui (sebelumnya) 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()
;
Hmm menarik. Saat kita menambahkan model ke koleksi, __byId_ menambahkan dua properti: model.id dan model.cid, referensinya ke model. Masalah pada baris 1134, id === undefined , tetapi __byId_ berisi model.id - _'foo'_.
Koleksi tidak memiliki logika khusus saat mengubah model.id menjadi nilai == null , periksa baris 1183.
Anda juga dapat mengubah unset untuk set _null_ atau _undefined_. this.model.set('id', null);
PS: Saya pikir Anda tidak perlu mengatur id model Anda ke nol atau tidak terdefinisi, itu anti pola.
Ya — Anda tidak boleh melakukan ini, tetapi ini masih bug.
Kita harus memperbaikinya dengan memastikan bahwa jika id
berubah dari nilai menjadi null
, kita delete this._byId[id]
terlebih dahulu.
Jika Anda menghapus model dari koleksi tanpa menggunakan acara, model akan berfungsi seperti yang diharapkan. Masalahnya ada di _onModelEvent
yang memeriksa apakah nama acara adalah change
, ketika nama acara sebenarnya yang dikirim dalam kasus ini adalah change:id
.
Komentar yang paling membantu
Ya — Anda tidak boleh melakukan ini, tetapi ini masih bug.
Kita harus memperbaikinya dengan memastikan bahwa jika
id
berubah dari nilai menjadinull
, kitadelete this._byId[id]
terlebih dahulu.