Backbone: 集合不会清除对已删除模型的内部 `_byId` 引用

创建于 2017-09-22  ·  3评论  ·  资料来源: jashkenas/backbone

请在下面找到我能理解的最简洁的复制 Backbone 应用程序中导致Collection进入内部混乱状态的一系列步骤。

可以在此JSFiddle 中找到工作副本。

它展示的是collection保持对remove() -ed Model的内部( _byId )引用。 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 更改为value == null 时,集合没有一些特殊的逻辑,请检查第 1183 行。

您也可以更改未设置设置_null_ 或 _undefined_。 this.model.set('id', null);

PS:我认为您永远不需要将模型 ID 设置为 null 或未定义,这是反模式。

backbone_remove

backbone_model_event

是的 - 你永远不应该这样做,但这仍然是一个错误。

我们应该通过确保如果id从一个值变为null ,我们首先delete this._byId[id]

如果您在不使用事件的情况下从集合中删除模型,它会按预期工作。 问题出在_onModelEvent ,它检查事件名称是否为change ,而在这种情况下发送的实际事件名称为change:id

此页面是否有帮助?
0 / 5 - 0 等级