A continuación, encontrará la reproducción más concisa que pude comprender de una secuencia de pasos en una aplicación Backbone que lleva a Collection
entrar en un estado de confusión interna.
Se puede encontrar una copia de trabajo en este JSFiddle .
Lo que demuestra es una collection
mantiene una referencia interna ( _byId
) a una remove()
-ed Model
. Ese Model
ya no es parte de collection.models
, sin embargo, aún se puede recuperar a través de su (anterior) 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()
;
Mmmm interesante. Cuando agregamos modelo a colección, __byId_ agrega dos propiedades: model.id y model.cid, su referencia al modelo. Problema en la línea 1134, id === undefined , pero __byId_ contiene model.id - _'foo'_.
La colección no tiene una lógica especial cuando cambia model.id a value == null , verifique la línea 1183.
También puede cambiar unset a set _null_ o _undefined_. this.model.set ('id', nulo);
PD: Creo que nunca necesitas establecer tu modelo de identificación en nulo o indefinido, es anti patrón.
Sí, nunca deberías hacer esto, pero sigue siendo un error.
Debemos arreglar esto asegurándonos de que si un id
está cambiando de un valor a null
, nosotros delete this._byId[id]
primero.
Si elimina un modelo de una colección sin el uso de un evento, funciona como se esperaba. El problema está en _onModelEvent
que comprueba si el nombre del evento es change
, cuando el nombre real del evento que se envía en este caso es change:id
.
Comentario más útil
Sí, nunca deberías hacer esto, pero sigue siendo un error.
Debemos arreglar esto asegurándonos de que si un
id
está cambiando de un valor anull
, nosotrosdelete this._byId[id]
primero.