Backbone: Коллекция не удаляет внутреннюю ссылку _byId на удаленную модель

Созданный на 22 сент. 2017  ·  3Комментарии  ·  Источник: jashkenas/backbone

Ниже вы можете найти кратчайшее воспроизведение, которое я смог понять, последовательности шагов в приложении Backbone, которое приводит к тому, что Collection входит в состояние внутренней неразберихи.

Рабочую копию можно найти в этом JSFiddle .

Он демонстрирует, что collection сохраняет внутреннюю ( _byId ) ссылку на remove() -ed Model . Этот Model больше не является частью collection.models , однако его все еще можно получить с помощью его (бывшего) 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()
;

Самый полезный комментарий

Да, вы никогда не должны этого делать, но это все еще ошибка.

Мы должны исправить это, убедившись, что если id меняется со значения на null , сначала мы delete this._byId[id] .

Все 3 Комментарий

Хм, интересно. Когда мы добавляем модель в коллекцию, __byId_ добавляет два свойства: model.id и model.cid, их ссылку на модель. Ошибка в строке 1134, id === undefined , но __byId_ содержит model.id - _'foo'_.

Коллекция не имеет особой логики при изменении model.id на значение == null , проверьте строку 1183.

Также вы можете изменить незаданы для множества _null_ или _undefined_. this.model.set ('идентификатор', ноль);

PS: Я думаю, вам никогда не нужно устанавливать идентификатор модели на null или undefined, это антипаттерн.

backbone_remove

backbone_model_event

Да, вы никогда не должны этого делать, но это все еще ошибка.

Мы должны исправить это, убедившись, что если id меняется со значения на null , сначала мы delete this._byId[id] .

Если вы удалите модель из коллекции без использования события, она будет работать должным образом. Проблема заключается в _onModelEvent который проверяет, является ли имя события change , когда фактическое имя события, отправляемое в этом случае, - change:id .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги