Backbone.js空数组属性

cor*_*ram 13 javascript arrays 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);

        // ...
    }
});
Run Code Online (Sandbox Code Playgroud)

然后我通过添加一个小部件addWidget.尝试getWidget我得到的结果(在Chrome中)是这样的:

Object
    widgets: Array[1]
        0: child
        length: 1
        __proto__: Array[0]
    __proto__: Object
[]
Run Code Online (Sandbox Code Playgroud)

它显示记录时窗口小部件不为空,this.attributes但在记录时显示为空this.attributes.widgets.有谁知道会导致什么?

编辑 我已经更改了模型以在初始化方法中实例化窗口小部件数组,以避免跨多个实例的引用,并且我开始使用骨架嵌套而没有运气.

mu *_*ort 22

小心信任控制台,通常会出现异步行为,可能会让您失望.

你期望console.log(x)表现得像这样:

  1. 你打电话console.log(x).
  2. x 被转储到控制台.
  3. 在您console.log(x)致电后立即继续执行该声明.

但事实并非如此,现实更像是这样:

  1. 你打电话console.log(x).
  2. 浏览器获取引用x,并将"真实" console.log调用排队等待以后.
  3. 运行(或不运行)各种其他JavaScript.
  4. 后来,console.log从通话(2)各地得到倾销的当前状态x到控制台,但这x并不一定匹配x,因为它是在(2) .

在你的情况下,你这样做:

console.log(this.attributes);
console.log(this.attributes.widgets);
Run Code Online (Sandbox Code Playgroud)

所以你在(2)有类似的东西:

         attributes.widgets
             ^         ^
             |         |
console.log -+         |
console.log -----------+
Run Code Online (Sandbox Code Playgroud)

然后在(3)中发生了一些有效的事情this.attributes.widgets = [...](即改变了attributes.widget参考),因此,当(4)到来时,你有这样的:

         attributes.widgets // the new one from (3)
             ^
             |
console.log -+
console.log -----------> widgets // the original from (1)
Run Code Online (Sandbox Code Playgroud)

这让你看到两个不同的版本widgets:新的一个在(3)中收到的东西和原始的是空的.

当你这样做:

console.log(_(this.attributes).clone());
console.log(_(this.attributes.widgets).clone());
Run Code Online (Sandbox Code Playgroud)

你抓住的副本this.attributesthis.attributes.widgets附加到该console.log电话,以(3)将不会与您参考干扰,你在控制台中看到有意义的结果.

这就是答案:

它显示记录时窗口小部件不为空,this.attributes但在记录时显示为空this.attributes.widgets.有谁知道会导致什么?

至于潜在的问题,你可能在fetch某个地方有一个呼叫而你没有考虑它的异步行为.解决方案可能是绑定到事件"add""reset"事件.

  • 关于tesis的很棒的解释_"`console.log()`可以欺骗你"_ :) (6认同)
  • @shim:`console.log(_(pancakes).clone())`或`console.log(model.toJSON())`如果需要获取快照而不用担心`console的引用问题,则很方便. log`. (2认同)

ims*_*sky 0

使用 Chrome 和 Firefox 进行测试: http: //jsfiddle.net/imsky/XBKYZ/

var s = new Session;
s.addWidget({"name":"test"});
s.getWidget()
Run Code Online (Sandbox Code Playgroud)

控制台输出:

Object
widgets: Array[1]
__proto__: Object

[
Object
name: "test"
__proto__: Object
] 
Run Code Online (Sandbox Code Playgroud)