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()
;
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.
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
.
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 ändernnull
, wirdelete this._byId[id]
zuerst.