Backbone: Sammlung löscht keine interne `_byId`-Referenz auf ein entferntes Modell

Erstellt am 22. Sept. 2017  ·  3Kommentare  ·  Quelle: jashkenas/backbone

Nachfolgend finden Sie die knappste Reproduktion, die ich von einer Abfolge von Schritten in einer Backbone-Anwendung ergründen konnte, die dazu führt, dass Collection in einen Zustand interner Verwirrung geraten.

Eine Arbeitskopie finden Sie in dieser JSFiddle .

Was es demonstriert, ist ein collection , das eine interne Referenz ( _byId ) auf ein remove() -ed Model . Dieses Model ist nicht mehr Teil von collection.models , kann jedoch weiterhin über sein (früheres) id abgerufen werden.

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

Hilfreichster Kommentar

Ja – Sie sollten dies niemals tun, aber es ist immer noch ein Fehler.

Wir sollten dieses Problem beheben , indem Sie sicherstellen , dass , wenn ein id wird von einem Wert zu ändern null , wir delete this._byId[id] zuerst.

Alle 3 Kommentare

Hmm, interessant. Wenn wir der Sammlung ein Modell hinzufügen, fügt __byId_ zwei Eigenschaften hinzu: model.id und model.cid, ihre Referenz auf das Modell. Ausgabe in Zeile 1134, ID === undefined , aber __byId_ enthält model.id - _'foo'_.

Collection hat keine spezielle Logik, wenn model.id in value == null geändert

Sie können auch ungesetzt auf Set _null_ oder _undefined_ ändern. this.model.set('id', null);

PS: Ich denke, Sie müssen Ihre Modell-ID nie auf null oder undefiniert setzen, es ist ein Anti-Muster.

backbone_remove

backbone_model_event

Ja – Sie sollten dies niemals tun, aber es ist immer noch ein Fehler.

Wir sollten dieses Problem beheben , indem Sie sicherstellen , dass , wenn ein id wird von einem Wert zu ändern null , wir delete this._byId[id] zuerst.

Wenn Sie ein Modell ohne Verwendung eines Ereignisses aus einer Sammlung entfernen, funktioniert es wie erwartet. Das Problem liegt in _onModelEvent das prüft, ob der Name des Ereignisses change , während der tatsächliche Ereignisname, der in diesem Fall gesendet wird, change:id .

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen