Backbone.js的bug?

时间:2012-07-26 06:53:20

标签: javascript backbone.js

我在test.html中有以下内容:

<script>
var Foo = Backbone.Model.extend({
  initialize: function(options) {
    console.log('hello!');
  }
});
var Bar = Backbone.Collection.extend({
  model: Foo
});
var m = new Bar({});
</script>

事实证明,当变量m被初始化时,会调用Foo的initialize函数。因此,在Firebug控制台中,我得到'你好!'。当我注释掉这一行:

model: Foo,

没有'你好!'在控制台输出中。因此,声明集合的模型会调用该模型的initialize函数。我认为这种行为有点傻。我没有读过主干代码,但这有什么原因吗?

3 个答案:

答案 0 :(得分:3)

嗯,代码的行为没有任何问题 在集合定义中传递模型时,指定该集合中的每个模型都为Foo类型 初始化集合new Bar({})时,将模型传递给集合(尽管如@alexanderb所述,我认为集合需要一个数组作为第一个参数)并初始化它,从而输出{{1} }。
例如,如果未将任何模型传递给集合构造函数:

'hello!'

没有控制台输出,另一方面,如果要传递一个对象数组,那么该集合将初始化所有提供的模型:

new Bar();// no console output

答案 1 :(得分:1)

我相信集合的构造函数需要模型的数组。所以,你应该做的是:

var collection = new Bar( [ {} ] );

在那里,应该调用模型的初始化方法。

答案 2 :(得分:0)

经过一番调查后我发现了,Backbone.Collection功能如下:

var Collection = Backbone.Collection = function(models, options) {
  options || (options = {});
  if (options.model) this.model = options.model;
  if (options.comparator !== void 0) this.comparator = options.comparator;
  this._reset();
  this.initialize.apply(this, arguments);
  if (models) this.reset(models, {silent: true, parse: options.parse});
};

因此,如果您为此集合创建初始化方法

initialize: function() {
  console.log('hello collection!');   
}

您会注意到hello集合是在模型的hello之前记录的。因此,模型初始化必须来自reset - 调用之后的initialize函数。 rest将不会被调用,除非您将模型传递到您的集合中,您很快就会看到它,但实际上在

var m = new Bar({});

Backbone将{}解释为模型,从而在reset - 函数中初始化它。但{}不是你说的模范吗?好吧,Backbone对此并不太挑剔,它只需要一个可以包含或不包含模型属性的哈希数组。 reset - 函数最终会导致add - 函数,最后所有道路都会转到罗马,或者我应该说_prepareModel - 函数

_prepareModel: function(attrs, options) {
  if (attrs instanceof Model) {
    if (!attrs.collection) attrs.collection = this;
    return attrs;
  }
  options || (options = {});
  options.collection = this;
  var model = new this.model(attrs, options);
  if (!model._validate(model.attributes, options)) return false;
  return model;
}

这里发生的事情是Collection检查它是否已经传递了模型或属性的散列,并且在属性散列的情况下,它只是根据其定义的模型创建一个新模型并传递该散列

希望这不仅可以解决问题,还可以解释那里发生的事情。当然,我热烈鼓励每个人阅读主干源代码the baddest OG of documentation