1

我有 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。

没有其他代码触及这些子集合,也没有其他方法修改它。我的视图的初始化方法中的两个调用是唯一影响集合的东西。

我觉得我的范围有问题,但我看不出我做错了什么。有任何想法吗?

4

1 回答 1

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"]
[]
于 2012-06-04T19:20:07.690 回答