猿问

Backbone.js空数组属性

我在Backbone.js模型中遇到一个奇怪的问题,其中数组成员显示为空白。看起来像这样:


var Session = Backbone.Model.extend({

    defaults: {

        // ...

        widgets: []

    },

    addWidget: function (widget) {

        var widgets = this.get("widgets");


        widgets.push(widget);

        this.trigger("change:widgets", this, widgets);

    },

    // ...

    // I have a method on the model to grabbing a member of the array

    getWidget: function (id) {

        console.log(this.attributes);

        console.log(this.attributes.widgets);


        // ...

    }

});

然后,我通过添加小部件addWidget。尝试getWidget结果时(在Chrome中)是这样的:


Object

    widgets: Array[1]

        0: child

        length: 1

        __proto__: Array[0]

    __proto__: Object

[]

它表明在记录时窗口小部件不是空的,this.attributes但在记录时它显示为空this.attributes.widgets。有人知道会导致什么吗?


编辑 我已经更改了模型,以在初始化方法中实例化小部件数组,以避免在多个实例之间进行引用,并且我开始使用没有任何运气的主干嵌套。


隔江千里
浏览 281回答 3
3回答

回首忆惘然

注意信任控制台,通常会有异步行为会使您绊倒。您期望console.log(x)表现得像这样:你打电话console.log(x)。x 被转储到控制台。console.log(x)调用后立即执行语句。但这不是发生的情况,实际情况更像是这样:你打电话console.log(x)。浏览器获取对的引用x,并将“真实” console.log调用排队,以备后用。JavaScript的其他各个部分都运行(或不运行)。后来,console.log从通话(2)各地得到倾销的当前状态x到控制台,但这x并不一定匹配x,因为它是在(2) 。就您而言,您正在执行以下操作:console.log(this.attributes);console.log(this.attributes.widgets);所以你在(2)有这样的东西:         attributes.widgets             ^         ^             |         |console.log -+         |console.log -----------+然后在(3)中发生了一些事情,它有效地做到了this.attributes.widgets = [...](即更改了attributes.widget引用),因此,当(4)出现时,您将得到以下结果:         attributes.widgets // the new one from (3)             ^             |console.log -+console.log -----------> widgets // the original from (1)这使您看到两种不同的版本widgets:新版本收到(3)中的内容,而原始版本为空。执行此操作时:console.log(_(this.attributes).clone());console.log(_(this.attributes.widgets).clone());你抓住的副本this.attributes和this.attributes.widgets附加到该console.log电话,以(3)将不会与您参考干扰,你在控制台中看到有意义的结果。这就是答案:它表明在记录时窗口小部件不是空的,this.attributes但在记录时它显示为空this.attributes.widgets。有人知道会导致什么吗?至于潜在的问题,您可能在fetch某个地方打了电话,而没有考虑到它的异步行为。解决方案可能是绑定到"add"or "reset"事件。

MMTTMM

请记住,[]在JS中,它只是的别名new Array(),并且由于对象是通过引用传递的,因此您的Session模型的每个实例都将共享同一数组对象。这会导致各种问题,包括数组似乎为空。要按照您想要的方式工作,您需要在构造函数中初始化小部件数组。这将为每个Session对象创建一个唯一的小部件数组,并可以缓解您的问题:var Session = Backbone.Model.extend({    defaults: {        // ...        widgets: false    },    initialize: function(){        this.set('widgets',[]);    },    addWidget: function (widget) {        var widgets = this.get("widgets");        widgets.push(widget);        this.trigger("change:widgets", this, widgets);    },    // ...    // I have a method on the model to grabbing a member of the array    getWidget: function (id) {         console.log(this.attributes);        console.log(this.attributes.widgets);    // ...    }});
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答