Backbone bootstrapped集合未正确初始化

nac*_*son 6 javascript backbone.js

我有一个问题,这很难被注意到,因为大多数情况下一切都有效.只有当我试图在我的集合初始化函数中操作我的数据时才发现问题.

骨干文档位于http://backbonejs.org/#Collection-constructor

"如果你定义了一个初始化函数,它将在创建集合时被调用."

所以我解释为,我的初始化函数直到我的模型设置后才会运行."这听起来很理想,"我说,但后来我遇到了这个.

我的引导代码如下:

new MyCollection(<?php if ($data) {echo json_encode($data);} ?>);
Run Code Online (Sandbox Code Playgroud)

我的收藏:

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

    initialize: function() { 
        console.log(this); 
        console.log(this.length);
        this.each(function(model) {
            console.log(model);
        });
    } 
});  
Run Code Online (Sandbox Code Playgroud)

我得到了奇怪的结果.

第一个console.log(this);是预期的集合对象:

{ 
    .... 
    models: [3], 
    length: 3 
    .... 
} 
Run Code Online (Sandbox Code Playgroud)

第二个console(this.length);打印出来的号码0

里面的控制台this.each()没有显示出来.

发生了什么?

mu *_*ort 11

Collection构造函数如下所示:

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

一步步:

  1. 这个this._reset()电话有一个this.length = 0.
  2. this.initialize.apply(...)是对你的initialize方法的调用.
  3. this.reset(...)会调用add添加的车型.该add调用将更新集合modelslength属性.

所以,当initialize被调用时,你就必须this.length == 0this.models将是一个空数组,因为只有_reset将一直在这里调用.现在我们可以很容易地看出为什么this.each不做任何事情以及为什么console.log(this.length)0.

但为什么console.log(this)告诉我们我们有一个人口密集的收藏?好吧,console.log不会马上发生,它只是抓住对它的参数的引用并稍后将某些东西记录到控制台; 由时间console.log获取各地的东西放在控制台,你必须通过得到(3)以上,这意味着,你将有this.modelsthis.length,你希望看到的.如果你说

console.log(this.toJSON());
Run Code Online (Sandbox Code Playgroud)

要么:

console.log(_(this.models).clone())
Run Code Online (Sandbox Code Playgroud)

console.logconsole.log写入控制台时,您将看到被调用时的状态而不是状态.

文档并没有明确说明在initialize调用时应该准备什么,所以你被卡在源代码中.这不是理想的,但至少Backbone源是干净和直接的.

您会注意到这样initialize称呼:

this.initialize.apply(this, arguments);
Run Code Online (Sandbox Code Playgroud)

arguments在那里意味着initialize将获得相同的参数构造函数,因此你可以看看在那里,如果你想要的东西:

initialize: function(models, options) {
    // The raw model data will be in `models` so do what
    // needs to be done.
}
Run Code Online (Sandbox Code Playgroud)