6

ほとんどの場合、すべてが機能するため、気付くのが非常に困難な問題があります。問題が見つかったのは、コレクションの初期化関数でデータを操作しようとしたときだけでした。

http://backbonejs.org/#Collection-constructorのバックボーン ドキュメント

「初期化関数を定義すると、コレクションの作成時に呼び出されます。」

そのため、モデルが設定されるまで初期化関数は実行されないと解釈しました。「それは理想的ですね」と私は言いましたが、私はこれに出くわしました。

私のブートストラップコードは次のとおりです。

new MyCollection(<?php if ($data) {echo json_encode($data);} ?>);

私のコレクション:

var MyCollection = Backbone.Collection.extend({
    model: MyModel,

    initialize: function() { 
        console.log(this); 
        console.log(this.length);
        this.each(function(model) {
            console.log(model);
        });
    } 
});  

奇妙な結果が得られました。

1 つ目console.log(this);は、期待どおりのコレクション オブジェクトでした。

{ 
    .... 
    models: [3], 
    length: 3 
    .... 
} 

そして2番目console(this.length);は数字を出力しました0

内部のコンソールthis.each()は表示されませんでした。

何が起こっていますか?

4

2 に答える 2

11

Collection コンストラクターは次のようになります

var Collection = Backbone.Collection = function(models, options) {
  //...
  this._reset();
  this.initialize.apply(this, arguments);
  //...
  this.reset(models, {silent: true, parse: options.parse});
  //...
};

ステップバイステップ:

  1. this._reset()呼び出しはthis.length = 0.
  2. メソッドのthis.initialize.apply(...)呼び出しinitializeです。
  3. は、モデルを追加するためにthis.reset(...)呼び出します。addこの呼び出しにより、コレクションとプロパティaddが更新されます。modelslength

したがって、initializeが呼び出されると、ここでは のみが呼び出されるため、空配列になりthis.length == 0ます。これで、 が何もしない理由と と言う理由が簡単にわかります。this.models_resetthis.eachconsole.log(this.length)0

しかし、なぜ はconsole.log(this)、データが取り込まれたコレクションがあると教えてくれるのでしょうか? console.logすぐには実行されません。引数への参照を取得し、少し後に何かをコンソールに記録するだけです。console.logコンソールに何かを配置する頃には、上記の (3) を完了しているthis.modelsことになりthis.lengthます。あなたが言うなら

console.log(this.toJSON());

また:

console.log(_(this.models).clone())

がコンソールに書き込むconsole.logときの状態ではなく、 が呼び出されたときの状態が表示されます。console.log

ドキュメントは、 が呼び出されたときに準備ができているはずのものについて正確に明示されていないinitializeため、ソースをトレースするのに行き詰まります。これは理想的ではありませんが、少なくともバックボーン ソースはクリーンで単純です。

initialize次のように呼び出されることに気付くでしょう。

this.initialize.apply(this, arguments);

そこargumentsにあるということは、コンストラクターと同じ引数を受け取ることを意味するinitializeので、必要に応じてそこを見ることができます。

initialize: function(models, options) {
    // The raw model data will be in `models` so do what
    // needs to be done.
}
于 2012-09-22T02:38:05.953 に答える
1

ブートストラップが正しくありません。コレクションの reset() メソッドを使用して、コレクション内のリセット イベントをリッスンする必要があります。

ブートストラップ コード:

var collection = new MyCollection;
collection.reset(<?php if ($data) { echo json_encode($data); } ?>);

コレクション コード:

var MyCollection = Backbone.Collection.extend({
    model: MyModel,

    initialize: function() {
        this.on("reset", this.foobar);
    },

    foobar: function(collection) {
       console.log(this); // will be the same
       console.log(this.length); //  will equal 3
       this.each(function(model) {
           console.log(model); // will output a console for each model.
       });
    }

});
于 2012-09-22T05:07:49.880 に答える