我有一个问题,很难注意到,因为大多数情况下一切正常。只有当我试图在我的集合初始化函数中操作我的数据时才发现问题。
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()
内的控制台没有显示。
发生了什么事?
答案 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});
//...
};
一步一步:
this._reset()
来电this.length = 0
。this.initialize.apply(...)
是对initialize
方法的调用。this.reset(...)
会调用add
来添加模型。 add
调用将更新集合的models
和length
属性。因此,当调用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.
});
}
});