javascript - 为什么我的 View 在 Backbone 中的数组长度不正确?

标签 javascript jquery backbone.js

我有 3 个 View ,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 个 child ,我希望它打印出 5 五次。相反,它打印出一个运行总数,5、10、15、20、25。

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

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

最佳答案

您在 View 中定义的属性:

var V = Backbone.View.extend({
    p: [ ],
    ...
});

没有深度复制到实例,它们仍然附加到 V 的原型(prototype),因此在 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"]
[]

您可能已经预料到了。

如果你想使用一个数组作为 View 实例的属性,你应该在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"]
[]

关于javascript - 为什么我的 View 在 Backbone 中的数组长度不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10885854/

相关文章:

php - 自定义 wordpress 主题以创建粘性页脚

javascript - 有没有办法将用户创建的方法与 Backbone 方法分开?

javascript - 创建类似于 Google 电子邮件表单的 Angular 电子邮件表单

javascript - 将一个文本分成多个文本

javascript - 将 RTL 语言音译为 LTR 语言的通用(粗略)算法

javascript - 是否可以将类分配给 :root?

javascript - Jquery 验证

加载 Ng-Repeat 元素后运行的 jQuery Swiper 脚本

javascript - 如何在模型获取时将 1 转换为 true 或将 0 转换为 false

php - 如何从服务器端的获取请求访问 Backbone 模型 ID