我有一群动物。
App.Collections.Animals extends Backbone.Collection
model: App.Animal
url: '/animals/' #returns json
这些动物类:
App.Models.Animal extends Backbone.Model
App.Models.Monkey extends App.Models.Animal
defaults:{type:'Monkey'}
App.Models.Cat extends App.Models.Animal
defaults:{type:'Cat'}
App.Models.Dog extends App.Models.Animal
defaults:{type:'Dog'}
当集合填充JSON(记录包含类型属性)时,我希望模型被实例化为子类模型(Monkey,Cat,Dog)而不是Animal。你怎么能做到这一点?
答案 0 :(得分:12)
来自Backbone documentation:
集合也可以通过覆盖它来包含多态模型 具有返回模型的函数的属性。
var Library = Backbone.Collection.extend({
model: function(attrs, options) {
if (condition) {
return new PublicDocument(attrs, options);
} else {
return new PrivateDocument(attrs, options);
}
}
});
答案 1 :(得分:6)
解决方案很简单(请原谅JS,我不知道CoffeeScript):
var SmartZoo = Backbone.Collection.extend({
model: function (attrs, options) {
// This code assumes that the object looks something like '{ type: "Cat", ... }'.
switch (attrs.type) {
case 'Cat':
return new Cat(attrs, options);
case 'Dog':
return new Dog(attrs, options);
default: // Unknown subclass
return new Animal(attrs, options);
}
}
});
你必须:
这是一个JSFiddle,它显示了这个多态集合:http://jsfiddle.net/FiddlerOnTheTarmac/uR2Sa/
答案 2 :(得分:0)
覆盖主干集合的_prepareModel。集合new在定义时使用子类,否则使用默认模型。
class App.Collections.Animals extends Backbone.Collection
model: App.Models.Animal
_prepareModel: (attrs, options) ->
if attrs instanceof Backbone.Model
attrs.collection = @
return attrs
options || (options = {})
options.collection = @
model_class = APP.Models[attrs.ntype] or this.model
model = new model_class(attrs, options)
if (!model._validate(attrs, options))
false
else
model