Backbone.js未使用Collection模型值

时间:2011-08-31 23:48:30

标签: 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();

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

我错过了什么?我可以这样做吗?

修改 不确定为什么这对文档有效,但以下工作。 Backbone 5.3

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

1 个答案:

答案 0 :(得分:7)

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

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

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

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

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

var folderItemDef = { ... };

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

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

App.Collections.FolderItems = Backbone.Collection.extend(folderItemsDef);

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

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

App.Collection.extend({
  model: undefined
});

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

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