Backbone.js未使用Collection模型值

Can*_*and 4 backbone.js

Backbone没有使用为集合指定的模型.我肯定错过了什么.

App.Models.Folder = Backbone.Model.extend({
  initialize: function() {
    _.extend(this, Backbone.Events);

    this.url = "/folders";
    this.items = new App.Collections.FolderItems();
    this.items.url = '/folders/' + this.id + '/items';
  },

  get_item: function(id) {
    return this.items.get(id);
  }
});

App.Collections.FolderItems = Backbone.Collection.extend({
  model: App.Models.FolderItem
});

App.Models.FolderItem = Backbone.Model.extend({
  initialize: function() {
    console.log("FOLDER ITEM INIT");
  }
});


var folder = new App.Models.Folder({id:id})
folder.fetch();

// later on change event in a view
folder.items.fetch();
Run Code Online (Sandbox Code Playgroud)

加载文件夹,然后加载项目,但它们不是FolderItem对象,永远不会调用FOLDER ITEM INIT.它们是基本的Model对象.

我错过了什么?我应该这样做吗?

编辑: 不知道为什么这对文档有效,但以下工作.骨干5.3

App.Collections.FolderItems = Backbone.Collection.extend({
  model: function(attributes) {
    return new App.Models.FolderItem(attributes);
  } 
});
Run Code Online (Sandbox Code Playgroud)

Der*_*ley 7

问题是您的模型与集合的声明顺序.基本上,您需要先定义模型.

App.Models.FolderItem = Backbone.Model.extend({...});

App.Collections.FolderItems = Backbone.Collection.extend({
  model: App.Models.FolderItem
});
Run Code Online (Sandbox Code Playgroud)

原因是骨干对象是使用对象文字语法定义的,这意味着它们在定义时立即进行评估.

此代码功能相同,但说明了对象的字面性:

var folderItemDef = { ... };

var folderItemsDef = {
  model: App.Models.FolderItem
}

App.Models.FolderItem = Backbone.Model.extend(folderItemDef);

App.Collections.FolderItems = Backbone.Collection.extend(folderItemsDef);
Run Code Online (Sandbox Code Playgroud)

你可以在这个例子中看到,folderItemDef和folderItems Def都是对象文字,key: value在定义文字后立即对它们进行评估.

在原始代码中,您首先定义了集合.App.Models.FolderItem定义集合时,这意味着未定义.所以你基本上是这样做的:

App.Collection.extend({
  model: undefined
});
Run Code Online (Sandbox Code Playgroud)

但是,通过将模型定义移动到集合定义之上,集合将能够找到模型并且它将正确关联.

FWIW:设置集合模型的函数版本工作的原因是,在执行应用程序并将模型加载到集合中之前,不会评估函数.那时,javascript解释器已经找到了模型的定义,并且正确加载了它.