0

我在 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被初始化时,initializeFoo 的函数被调用。因此,在 Firebug 控制台中,我得到“你好!”。当我注释掉这一行时:

model: Foo,

没有“你好!” 在控制台输出中。因此,为集合声明模型会调用该模型的initialize函数。我认为这种行为有点愚蠢。我还没有通读骨干代码,但这是有原因的吗?

4

3 回答 3

3

好吧,代码的行为没有任何问题。
当您在集合定义中传递模型时,您指定该集合中的每个模型都是 type Foo
当您初始化集合new Bar({})时,您将模型传递给集合(尽管正如@alexanderb 所说,我认为集合需要一个数组作为第一个参数)并对其进行初始化,从而输出'hello!'.
例如,如果您不将任何模型传递给集合构造函数:

new Bar();// no console output

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

new Bar([{},[},{}]);// will output 'hello!' 3 times
于 2012-07-26T07:03:44.643 回答
1

我相信集合的构造者期望模型数组。所以,你应该做的是:

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

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

于 2012-07-26T07:05:56.623 回答
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});
};

因此,如果您像这样为您的 Collection 创建一个初始化方法

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

您会注意到 hello 集合记录在模型的 hello 之前。所以模型初始化必须来自-callreset之后的函数。除非您将模型传递到您的收藏中,否则不会被调用,您乍一看似乎没有这样做,但实际上在initializerest

var m = new Bar({});

Backbone 将 解释{}为模型,因此在reset-function 中对其进行初始化。但是{}你说的不是模特吗?嗯,Backbone 对此并不太挑剔,它只需要一个可以包含或不包含模型属性的哈希数组。-functionreset最终导致add-function 最终所有道路都通向罗马,或者我应该说_prepareModel-function

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

这里发生的情况是,集合检查它是否已通过模型或属性散列,在属性散列的情况下,它只是根据其定义的模型创建一个新模型并传递该散列。

希望这不仅能解决问题,还能进一步阐明那里发生的事情。当然,我也热忱地提倡大家阅读骨干源代码,最糟糕的 OG 文档

于 2012-07-26T07:33:19.123 回答