为什么我的视图在骨干中的数组长度不正确

Why is my view's array length in Backbone incorrect?

本文关键字:数组 不正确 我的 视图 为什么      更新时间:2023-09-26

我有 3 个视图,ViewA 包含 ViewB 子项的集合,每个视图 B 包含一组 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。

没有其他代码触及这些子集合,并且到目前为止还没有其他方法对其进行修改。我的视图的初始化方法中的两个调用是唯一影响集合的事情。

感觉我有一个范围问题,但我看不出我做错了什么。有什么想法吗?

您在

视图中定义的属性:

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"]
[]