具有特定类型的Backbone.Js集合

时间:2011-05-19 15:59:00

标签: backbone.js

我有一个名为History的BackboneJS集合,它可以包含几个Backbone JS模型中的一个(从HistoryItem扩展而来自Backbone.Model),我试图找到一种方法在加载时重新创建,不幸的是它似乎BackboneJS集合只能在特定模型中指定,例如

HistoryCollection = Backbone.Model.extend({
  model: app.models.HistoryItem
})

我真正需要做的是确定每种类型,这是我想做的事情

 HistoryCollection = Backbone.Model.extend({   
  model: function(item) {
       return app.models[item.type];   } })

在我分叉Backbone实现这个之前的任何想法? (即能够采用函数的集合模型属性)

3 个答案:

答案 0 :(得分:7)

在firebug中玩耍......想出了一种方法,你可以覆盖集合的解析方法,而不是指定模型。您的解析实现基本上变成了一个简单的工厂,用于使用您想要的模型填充集合:

var BaseModel  = Backbone.Model.extend({
    meth: function(){ return 'Base method'; },
});

var SubModel = BaseModel.extend({
    meth: function(){ return 'Sub1 method'; }
});

var SubModel2 = BaseModel.extend({
    meth: function(){ return 'Sub2 method'; }
});

var ModelCollection = Backbone.Collection.extend({
    parse: function(data){
        var self = this;
        data.forEach(function(item){
            switch(item.type){
            case 1:
                self.add(new SubModel(data));
                break;
            case 2:
                self.add(new SubModel2(data));
                break;
            default:
                self.add(new BaseModel(data))
        }
});
    }
});

//Example Use
x = new ModelCollection;
x.parse([{type: 1},{type: 2}, {type: 99}]);
x.map(function(e){ return e.meth();});

答案 1 :(得分:4)

恕我直言,我更喜欢在集合中使用模型方法:

var MyCollection = Backbone.Collection.extend({
  model : function(attrs, options){
    switch (attrs.type) {
            case 1 :
                model = new ModelType1(attrs, options);
                break;

            case 2 :
                model = new ModelType2(attrs, options);
                break;

            default :
                model = new BaseModel(attrs, options);
                break;
    }
  }
});

或使用代理模型:

ProxyModel = Backbone.Model.extend({
 initialize: function() {
   switch (this.get('type')) {
     case 1 :
       model = new ModelType1(attrs, options);
       break;

     case 2 :
       model = new ModelType2(attrs, options);
       break;

     default :
       model = new BaseModel(attrs, options);
       break;
   }
   return new model;
 }
})


var MyCollection = Backbone.Collection.extend({
  model : ProxyModel,
});

答案 2 :(得分:0)

我刚刚实现了这个功能,并从Jake Dempsey的建议开始,但实际上你需要覆盖集合中的不同方法。这是我使用的代码:

var MyCollection = Backbone.Collection.extend({

    _prepareModel: function(model, options) {
        if (!(model instanceof Backbone.Model)) {
            var attrs = model;

            switch (attrs.type) {
                case 1 :
                    model = new ModelType1(attrs, { collection: this });
                    break;

                case 2 :
                    model = new ModelType2(attrs, { collection: this });
                    break;

                default :
                    model = new BaseModel(attrs, { collection: this });
                    break;
            }

            if (model.validate && !model._performValidation(attrs, options)) model = false;
        } else if (!model.collection) {
            model.collection = this;
        }

        return model;
    }

});

请注意,它是一种私有(ish)方法,因此在升级Backbone时要记住这一点。