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

发布于 2024-11-08 00:24:19 字数 503 浏览 0 评论 0原文

我有一个名为 History 的 BackboneJS 集合,它可以包含多个 Backbone JS 模型之一(从 HistoryItem 扩展,而 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 来实现这个之前有什么想法吗? (即集合模型属性能够接受函数)

I have a BackboneJS collection called History which can contain one of several Backbone JS models (which extend from HistoryItem which extends from Backbone.Model), I trying to find a way to have this recreated when loading, unfortunately it seems BackboneJS collection can only specify at particular model e.g.

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

What I really need to do is determine this per type, here is what I'd like to do

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

Any ideas before I fork Backbone to implement this? (i.e. a collection model attribute being able to take a function)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

£冰雨忧蓝° 2024-11-15 00:24:19

在 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();});

Playing around in firebug.. came up with an approach where you can override the parse method of collection instead of specifying the model. Your parse implementation basically becomes a simple factory for filling the collection with models that you want:

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();});
旧伤还要旧人安 2024-11-15 00:24:19

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

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,
});

IMHO, I prefer to play with the model method in the collection:

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;
    }
  }
});

or using a proxy model:

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,
});
成熟的代价 2024-11-15 00:24:19

我刚刚实现了此功能,并从 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 时要记住一些事情。

I've just implemented this feature and started off with Jake Dempsey's advice, however you actually need to override a different method in the collection. This is the code I used:

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;
    }

});

Note that it is a private(ish) method so something to keep in mind when upgrading Backbone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文