Backbone: Koleksi tidak menghapus referensi `_byId` internal ke model yang dihapus

Dibuat pada 22 Sep 2017  ·  3Komentar  ·  Sumber: jashkenas/backbone

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

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 menjadi null , kita delete this._byId[id] terlebih dahulu.

Semua 3 komentar

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.

backbone_remove

backbone_model_event

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 .

Apakah halaman ini membantu?
0 / 5 - 0 peringkat