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 つのアイテムがある場合、これも 5 であると予想viewBChildren.lengthされます。これは正しく、問題なく動作します。

私の問題は、印刷するときviewCChildren.lengthです。5CollectionB の各項目に 5 つの子がある場合、 5 回印刷されると予想されます。代わりに、累計 5、10、15、20、25 を出力します。

他のコードはこれらの子コレクションに触れておらず、他のメソッドはまだそれを変更していません。私のビューの初期化メソッドの 2 つの呼び出しは、コレクションに影響を与える唯一のものです。

スコープに問題があるような気がしますが、何が間違っていたのかわかりません。何か案は?

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 に答える