Backbone: La collection ne purge pas la référence interne `_byId` à un modèle supprimé

Créé le 22 sept. 2017  ·  3Commentaires  ·  Source: jashkenas/backbone

Veuillez trouver ci-dessous la reproduction la plus laconique que j'ai pu imaginer d'une séquence d'étapes dans une application Backbone qui conduit un Collection entrer dans un état de confusion interne.

Une copie de travail peut être trouvée dans ce JSFiddle .

Ce qu'il démontre est un collection gardant une référence interne ( _byId ) à un remove() -ed Model . Ce Model ne fait plus partie de collection.models , cependant, il peut toujours être récupéré via son (ancien) 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

Commentaire le plus utile

Oui, vous ne devriez jamais faire cela, mais c'est toujours un bug.

Nous devrions résoudre ce problème en nous assurant que si un id passe d'une valeur à null , nous delete this._byId[id] abord.

Tous les 3 commentaires

Hum ... intéressant. Lorsque nous ajoutons un modèle à une collection, __byId_ ajoute deux propriétés : model.id et model.cid, leur référence au modèle. Problème sur la ligne 1134, id === undefined , mais __byId_ contient model.id - _'foo'_.

La collection n'a pas de logique particulière lorsque vous modifiez model.id en value == null , vérifiez la ligne 1183.

Vous pouvez également modifier unset pour définir _null_ ou _undefined_. this.model.set('id', null);

PS: Je pense que vous n'avez jamais besoin de définir votre identifiant de modèle sur null ou indéfini, c'est anti-modèle.

backbone_remove

backbone_model_event

Oui, vous ne devriez jamais faire cela, mais c'est toujours un bug.

Nous devrions résoudre ce problème en nous assurant que si un id passe d'une valeur à null , nous delete this._byId[id] abord.

Si vous supprimez un modèle d'une collection sans utiliser d'événement, cela fonctionne comme prévu. Le problème réside dans _onModelEvent qui vérifie si le nom de l'événement est change , alors que le nom de l'événement envoyé dans ce cas est change:id .

Cette page vous a été utile?
0 / 5 - 0 notes