我的网页应用程序具有复合结构,即每个类别集合可以包含单独的项目和其他类别作为其行/节点/子级(在这里不确定正确的术语)。实际上,它比这还要简单一些,因为每个集合都由模型Category表示,因此每个Category集合都具有Item模型和Category模型作为其子级。
一般来说,在MVC中使用这种结构实现是否可行?更具体地说,在Backbone.js中,一个集合是否可以具有一个模型工厂(根据JSON的结构接收JSON并计算生成哪个模型),而不是静态模型属性:
我的网页应用程序具有复合结构,即每个类别集合可以包含单独的项目和其他类别作为其行/节点/子级(在这里不确定正确的术语)。实际上,它比这还要简单一些,因为每个集合都由模型Category表示,因此每个Category集合都具有Item模型和Category模型作为其子级。
一般来说,在MVC中使用这种结构实现是否可行?更具体地说,在Backbone.js中,一个集合是否可以具有一个模型工厂(根据JSON的结构接收JSON并计算生成哪个模型),而不是静态模型属性:
{
'id': 1,
'name': 'My 1st Category',
'children': [
{
'id': 2,
'name': 'My 2nd Category',
'children': []
},
{
'id': 1,
'name': 'An Item',
'price': 109.99
}
]
}
var CategoryCollection = Backbone.Collection.extend({
initialize: function(m, models) {
_.each(models, function(model) {
var modelObject = null;
if (model.price !== undefined) {
modelObject = new Item(model);
} else {
modelObject = new Category(model);
}
this.add(modelObject);
}, this);
}
});
虽然这种方法有些取巧,但您可以通过检查是否具有特定字段(例如我的示例中的price
),来确定模型的类型,创建模型对象,然后将其添加到集合中。
然后您可以这样调用它:
var myCollection = new CategoryCollection([], myJSON);
注意,你需要将一个空数组作为第一个参数传递,因为这是通常传递模型集合的方式。
稍后在使用集合时,你可以通过简单的 instanceof
检查来确定你正在处理一个 Item
或 Category
:
_.each(myCollection.models, function(model) {
if (model instanceof Item) {
console.log("It's an Item! Price: ", model.get("price"));
} else {
console.log("It's a Category!");
}
});
是的,您可以在Backbone的集合中使用工厂模式来创建模型。假设@kpeel's answer所建议的数据结构,您可以定义如下:
// Factory method
var CategoryOrItemFactory = function(data, options) {
if (data.children) {
return new Category(data, options);
} else {
return new Item(data, options);
}
};
// Model definitions
var Item = Backbone.Model.extend();
var Category = Backbone.Model.extend({
initialize: function() {
this.children = new Children(this.get("children"));
}
});
var Children = Backbone.Collection.extend({
model: CategoryOrItemFactory
});
// create the root item
var rootItem = new Category(rawData);
children
属性,例如: rootItem.children.get(2).get("name");
这里有一个jsFiddle与上面的代码可以玩耍。
可以的,我以前做过。我认为这些链接可能会对你有所帮助:http://documentcloud.github.com/backbone/#Collection-model
这是我在项目中使用的主要脚本之一:https://gist.github.com/b65893e0c2e3c46d3dc1
set
方法以解析传递的属性/JSON可能会奏效 - 当模型被初始化时调用它来设置传递的属性扩展默认值,无论是使用new Model({...})
还是使用collection.add([{...},...])
。 - Tom Tu_prepareModel
。它不应该消失 - 但例如,在backbone的主分支中,_add
和_remove
现在已经被删除了。 - Tom Tu