我有3个视图,ViewA包含一组ViewB子视图,每个ViewB包含一组ViewC子视图。
ViewA: Backbone.View.extend({
viewBChildren: [],
initialize: function() {
// Do stuff
var self = this;
// Generate children
this.model.get("CollectionB").each(function(b) {
var viewB = new ViewB({
// set properties
});
self.viewBChildren.push(viewB);
console.log(self.viewBChildren.length); // Prints out correctly
});
}
});
ViewB: Backbone.View.extend({
viewCChildren: [],
initialize: function() {
var self = this;
this.model.get("CollectionC").each(function (c) {
var viewC = new ViewC({
// Set properties
});
self.viewCChildren.push(viewC);
console.log(self.viewCChildren.length); // Prints out a running total
});
}
});
因此,如果我在CollectionB中有5个项目,我希望viewBChildren.length
也是5.这是真的并且工作正常。
我的问题是打印出viewCChildren.length
时。如果CollectionB中的每个项目有5个孩子,我希望它打印出5
五次。相反,它打印出一个运行总计,5,10,15,20,25。
没有其他代码会触及这些子集合,也没有其他方法可以修改它。我的视图初始化方法中的两个调用是影响集合的唯一方法。
我觉得我有一个范围问题,但我看不出我做错了什么。有什么想法吗?
答案 0 :(得分:4)
您在视图中定义的属性:
var V = Backbone.View.extend({
p: [ ],
...
});
未被深度复制到实例,它们会附加到V
的原型,因此会在V
及其所有实例之间共享。
考虑到这一点,我们可以看到发生了什么。每次这样做:
self.viewCChildren.push(viewC);
你实际上正在做ViewB.prototype.viewCChildren.push(viewC)
,这就是为什么你得到一个总计。
例如,如果我们这样做(http://jsfiddle.net/ambiguous/Z3QC6/):
var V = Backbone.View.extend({
a: [ ],
initialize: function() {
this.a.push('pancakes');
}
});
// The setTimeouts are to kludge around the asynchronous nature
// of some console.logs. Play with the times if you're seeing
// two element arrays for all the console.log calls.
var v1, v2;
console.log(V.prototype.a);
setTimeout(function() {
v1 = new V();
console.log(v1.a);
console.log(V.prototype.a);
}, 100);
setTimeout(function() {
v2 = new V();
console.log(v1.a);
console.log(v2.a);
console.log(V.prototype.a);
}, 500);
然后我们将在控制台中得到它:
[]
["pancakes"]
["pancakes"]
["pancakes", "pancakes"]
["pancakes", "pancakes"]
["pancakes", "pancakes"]
而不是
[]
["pancakes"]
[]
["pancakes"]
["pancakes"]
[]
你可能在期待。
如果要将数组用作视图实例属性,则应在initialize
中进行设置:
initialize: function() {
this.viewCChildren = [ ];
}
例如,这个(http://jsfiddle.net/ambiguous/BjCvf/):
var V = Backbone.View.extend({
a: [ ],
initialize: function() {
this.a = [ ];
this.a.push('pancakes');
}
});
// The rest as above
将生成此控制台输出:
[]
["pancakes"]
[]
["pancakes"]
["pancakes"]
[]