简体   繁体   English

Backbone.js错误?

[英]Backbone.js bug?

I have the following in test.html: 我在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>

As it turns out, when the variable m is initialized, the initialize function of Foo is called. 事实证明,在初始化变量m时,将调用Foo的initialize函数。 Thus, in the Firebug console, I get 'hello!'. 因此,在Firebug控制台中,我得到“ hello!”。 When I comment out the line: 当我注释掉该行时:

model: Foo,

There is no 'hello!' 没有“你好!” in the console output. 在控制台输出中。 Thus, declaring a model for a collection calls that model's initialize function. 因此,为集合声明模型将调用该模型的initialize函数。 I think this behavior is a bit silly. 我认为这种行为有点愚蠢。 I haven't read through backbones code, but is there a reason for this? 我没有阅读过骨干网代码,但是这有原因吗?

Well, there's nothing wrong with the behaviour of the code. 好吧,代码的行为没有错。
When you pass the model in the collection definition, you specify that every model in that collection will be of type Foo . 在集合定义中传递模型时,您指定该集合中的每个模型都将为Foo类型。
When you initialize the collection new Bar({}) , you pass a model to the collection (although, as @alexanderb stated, I think that the collections expects an array as a first argument) and it initializes it, thus outputting 'hello!' 当您初始化集合new Bar({}) ,您将模型传递给集合(尽管,如@alexanderb所述,我认为集合期望将数组作为第一个参数)并对其进行初始化,从而输出'hello!' .
For example, if you do not pass any models to the collection constructor : 例如,如果您不将任何模型传递给集合构造函数:

new Bar();// no console output

there will be no console output, and on the other hand, if you would pass an array of objects, then the collection would initialize all of the provided models : 没有控制台输出,另一方面,如果您传递对象数组,则该集合将初始化所有提供的模型:

new Bar([{},[},{}]);// will output 'hello!' 3 times

I believe the constuctor of collection is expecting the array of models. 我相信集合的构造者期望模型的阵列 So, what you should do is: 因此,您应该做的是:

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

There, the initialize method of model should be called. 在那里,应该调用模型的初始化方法。

After a bit of investigation here is what i found out, the Backbone.Collection function is as follows: 经过一番调查,我发现这里的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});
};

So if you create an initialize method for your Collection like this 因此,如果您像这样为您的Collection创建一个初始化方法

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

You will notice that the hello collection is logged before the hello from model. 您会注意到,在收集来自模型的问候之前,已记录了问候集合。 So the model initialisation must come from the reset function after the initialize -call. 因此,模型初始化必须来自initialize -call之后的reset函数。 rest won't be called unless you have models passed onto your collection, which you at a quick glance don't seem to be doing, but actually in 除非您将模型传递给您的收藏集,否则您将不会调用rest ,您乍一看似乎并没有这样做,但是实际上

var m = new Bar({});

Backbone interprets the {} as a model and thus initializes it in the reset -function. 骨干网将{}解释为模型,从而在reset函数中对其进行初始化。 But {} isn't a model you say? 但是{}不是您说的模型吗? Well, Backbone isn't too picky about that, it just needs an array of hashes that could or could not contain model attributes. 好吧,Backbone对此不太挑剔,它只需要一个可以包含或不包含模型属性的哈希数组。 The reset -function eventually leads to the add -function and finally all roads go to Rome, or should i say the _prepareModel -function 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;
}

What happens here is that the Collection checks whether or not it has been passed a model or a hash of attributes and in the hash-of-attributes case it just creates a new model based on its defined model and passes that hash along. 此处发生的情况是Collection会检查它是否已经传递了模型或属性哈希,在属性哈希的情况下,它只是基于其定义的模型创建新模型并将该哈希传递。

Hope this not only solves the problem, but sheds some additional light on what happened there. 希望这不仅可以解决问题,而且可以进一步说明那里发生的事情。 And of course I warmly promote for everyone to read up on the backbone source code, the baddest OG of documentation . 当然,我会热情地鼓励所有人阅读骨干源代码, 这是最糟糕的文档OG

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM