Backbone: A coleção não elimina a referência interna `_byId` para um modelo removido

Criado em 22 set. 2017  ·  3Comentários  ·  Fonte: jashkenas/backbone

Encontre abaixo a reprodução mais concisa que consegui imaginar de uma sequência de etapas em um aplicativo de Backbone que leva Collection a um estado de confusão interna.

Uma cópia de trabalho pode ser encontrada neste JSFiddle .

O que ele demonstra é um collection mantendo uma referência interna ( _byId ) para um remove() -ed Model . Esse Model não faz mais parte de collection.models , no entanto, ele ainda pode ser recuperado por meio de seu (antigo) 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

Comentários muito úteis

Sim - você nunca deve fazer isso, mas ainda é um bug.

Devemos corrigir isso nos certificando de que se um id está mudando de um valor para null , nós delete this._byId[id] primeiro.

Todos 3 comentários

Hmm interessante. Quando adicionamos o modelo à coleção, __byId_ adiciona duas propriedades: model.id e model.cid, sua referência ao modelo. Problema na linha 1134, id === indefinido , mas __byId_ contém model.id - _'foo'_.

A coleção não tem uma lógica especial ao alterar model.id para value == null , verifique a linha 1183.

Além disso, você pode alterar não definido para this.model.set ('id', nulo);

PS: Eu acho que você nunca precisa definir o id do modelo como nulo ou indefinido, é anti-padrão.

backbone_remove

backbone_model_event

Sim - você nunca deve fazer isso, mas ainda é um bug.

Devemos corrigir isso nos certificando de que se um id está mudando de um valor para null , nós delete this._byId[id] primeiro.

Se você remover um modelo de uma coleção sem o uso de um evento, ele funcionará conforme o esperado. O problema está em _onModelEvent que verifica se o nome do evento é change , quando o nome do evento real sendo enviado neste caso é change:id .

Esta página foi útil?
0 / 5 - 0 avaliações