Backbone bootstrapped集合未正确初始化

时间:2012-09-22 01:25:10

标签: javascript backbone.js

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

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);
        });
    } 
});  

我得到了奇怪的结果。

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

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

,第二个console(this.length);打印出数字0

this.each()内的控制台没有显示。

发生了什么事?

2 个答案:

答案 0 :(得分:11)

Collection构造函数looks like this

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属性。
  4. 因此,当调用initialize时,您将this.length == 0,而this.models将是一个空数组,因为此处仅调用_reset。现在,我们可以轻松了解为什么this.each没有做任何事情以及为什么console.log(this.length)0

    但为什么console.log(this)告诉我们我们有一个填充的集合?好吧,console.log不会马上发生,它只是抓住对它的参数的引用并稍后将某些内容记录到控制台;当console.log在控制台中放置某些内容时,您将通过上面的(3),这意味着您将拥有this.models和{ {1}}你期待看到的。如果你说

    this.length

    或:

    console.log(this.toJSON());
    

    console.log(_(this.models).clone()) 写入控制台时,您会看到调用console.log时的状态,而不是状态。

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

    您会注意到initialize的调用方式如下:

    initialize

    arguments表示this.initialize.apply(this, arguments); 将获得与构造函数相同的参数,因此您可以根据需要查看:

    initialize

答案 1 :(得分:1)

你引导不正确。您将需要使用Collection reset()方法,并在您的collecton中监听重置事件,如此

Bootstrap代码:

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.
       });
    }

});