我正在与一个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
。 有谁知道什么原因呢?
编辑我已经改变了模型实例的初始化方法,以避免在多个实例引用控件数组,我开始使用骨干嵌套 ,没有运气。
要小心信任控制台,往往是可以你绊倒异步行为。
你期待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)将不会与你的参考干扰,你在控制台中看到有意义的结果。
这是这个问题的答案:
它表明登录时Widgets是不是空this.attributes
但登录时,它显示为空this.attributes.widgets
。 有谁知道什么原因呢?
至于潜在的问题的话,你可能有一个fetch
打电话的地方你也不会考虑它的异步行为考虑在内。 该解决方案可能是绑定到一个"add"
或"reset"
事件。
请记住, []
在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);
// ...
}
});
经测试,在与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
]