为了账号安全,请及时绑定邮箱和手机立即绑定

Backbone.js空数组属性

Backbone.js空数组属性

隔江千里 2019-11-03 08:04:08
我在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。有人知道会导致什么吗?编辑 我已经更改了模型,以在初始化方法中实例化小部件数组,以避免在多个实例之间进行引用,并且我开始使用没有任何运气的主干嵌套。
查看完整描述

3 回答

?
回首忆惘然

TA贡献1847条经验 获得超11个赞

注意信任控制台,通常会有异步行为会使您绊倒。


您期望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"事件。



查看完整回答
反对 回复 2019-11-04
?
MMTTMM

TA贡献1869条经验 获得超4个赞

请记住,[]在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);

    // ...

    }

});




查看完整回答
反对 回复 2019-11-04
  • 3 回答
  • 0 关注
  • 280 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信