一个集合Backbone中的不同模型类型

时间:2014-12-30 19:47:05

标签: javascript backbone.js backbone-collections backbone-model

Backbone 1.1.2
下划线1.7.0
jQuery 1.11.1

我有一个包含邮件的集合。 我的消息可以是不同类型的(并且api中的端点对于每种类型都是不同的,但我有一个端点,允许我做一个请求并获取所有消息)

当Collection.fetch()时 我需要能够根据现有属性定义在填充集合时使用哪个模型。

我按照此处的建议尝试:A Backbone.js Collection of multiple Model subclasses 以及主干文档backbonejs.org

我的代码看起来像这样

model: function (attr, options) {
    if(attr.hasOwnProperty('prop')){
        return new PropModel(attr,options);
    }
    else if(attr.hasOwnProperty('another_prop')){
        new AnotherPropModel(attr,options);
    }
},

attr值只是一个很大的对象数组,所以如果不以某种方式遍历这个解决方案对我来说没有任何意义,那么它显然无法工作。

我是否正确处理此问题还有另一种方法吗?

--- ---- UPDATE

我也尝试在集合的Parse函数中执行此操作,我的集合只是空的

parse: function (resp, options) {
    _.each(resp, _.bind(function (r) {
        console.log(this);
        if(r.hasOwnProperty('prop')){
            this.add(new PropModel(r));
        }else{
            this.add(new AnotherPropModel(r));
        }
    },this));
}

2 个答案:

答案 0 :(得分:0)

您可以执行以下操作 - 对不同类型(如果可能)做出反应,然后提供不同的URL。然后,一旦JSON模型在模板中,您就可以按照自己喜欢的方式呈现HTML:

示例Json

"[{"id":1,"Type":"Person"},{"id":2,"Type":"Business"}]"

示范模型

var Person = Backbone.Model.extend({

    keyTypes: {
        Person: 'Person',
        Business: 'Business'
    },

    url: function() {
        // we are assuming only two types. Change logic if there are three or more types.
        return this.get('Type') === this.keyTypes.Person ? '/api/people' : '/api/businesss';
    }

});

<强>集合

var Collection = Backbone.Collection.extend({
    model: Person
});

查看

var View = Backbone.View.extend({

    initialize: function() {
        this.collection = new Collection()
            .on('fetch', this.render, this);
    },

    bootstrap: function() {
        this.collection.fetch();
    }

    render: function() {
        this.$el.html(_.template({
            models: this.collection.toJSON()
        }));
    }
})

** !!更新!! **

如果您仍想使用解析,则可以查看以下内容。

parse: function (data, options) {

    var models = [];
    _.each(data, function (entity) {
        // this is IE8 Safe....
        var model = Object.prototype.hasOwnProperty.call(entity,'prop') ? PropModel : AnotherPropModel;
        models.push(new model(entity));    
    });

    return models;
}

答案 1 :(得分:0)

所以解决方案是使用模型函数和返回的混合。

以下是解释:

首先我们有解析功能 这只是我们改变我们从服务器收到的响应的入口点

parse: function (resp, options) {
    return resp;
}

在我的情况下,服务器返回一个Object of Object as

{{1:data},{2:data}}

首先这很奇怪,显然需要解决。 重要的一点是: 当主干评估来自解析的响应返回时,它需要决定每个模型的中断位置,如定义新模型的那样。

Backbone将对象视为单个模型,在我的情况下,我有一个大对象,我得到了一个大模型......这就是为什么模型函数中的attrs参数是一大堆数据。

所以我只是在解析函数和Voila中改变了我的响应!模型函数中的所有内容都按预期工作:

以下是代码:

model: function (attr, options) {
    if(attr.hasOwnProperty('prop')){
        return new PropModel(attr,options);
    }
    else if (attr.hasOwnProperty('anotherProp')){
        return new AnotherPropModel(attr,options);
    }
},

parse: function (resp, options) {
    var response = [];
    _.each(resp, _.bind(function (r) {
        response.push(r);
    },this));
    return response;
}

我确定有一种更好的方法可以将对象解析为数组,但是现在这种方法有效,而且我再次微笑!!

本文引导我找到解决方案: A collection of muppets