Backbone.js的空数组属性(Backbone.js Empty Array Attribut

2019-06-17 10:40发布

我正在与一个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
[]

它表明登录时Widgets是不是空this.attributes但登录时,它显示为空this.attributes.widgets 。 有谁知道什么原因呢?

编辑我已经改变了模型实例的初始化方法,以避免在多个实例引用控件数组,我开始使用骨干嵌套 ,没有运气。

Answer 1:

要小心信任控制台,往往是可以你绊倒异步行为。

你期待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);

所以,你必须在(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.attributesthis.attributes.widgets被连接到console.log通话中,以便(3)将不会与你的参考干扰,你在控制台中看到有意义的结果。

这是这个问题的答案:

它表明登录时Widgets是不是空this.attributes但登录时,它显示为空this.attributes.widgets 。 有谁知道什么原因呢?

至于潜在的问题的话,你可能有一个fetch打电话的地方你也不会考虑它的异步行为考虑在内。 该解决方案可能是绑定到一个"add""reset"事件。



Answer 2:

请记住, []在JS只是一个别名new Array()由于对象是通过引用传递,你的Session模型的每个实例将共享相同的数组对象。 这导致各种问题,包括出现的是空数组。

为了使这项工作您想要的方式,你需要初始化你的widget阵列在构造函数中。 这将为每个会话对象的唯一控件数组,应该减轻您的问题:

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);
    // ...
    }
});


Answer 3:

经测试,在与Chrome和Firefox提琴: http://jsfiddle.net/imsky/XBKYZ/

var s = new Session;
s.addWidget({"name":"test"});
s.getWidget()

控制台输出:

Object
widgets: Array[1]
__proto__: Object

[
Object
name: "test"
__proto__: Object
] 


文章来源: Backbone.js Empty Array Attribute