一个集合中的不同模型类型 主干

Different model types in one collection Backbone

本文关键字:模型 类型 主干 一个 集合      更新时间:2023-09-26

Backbone 1.1.2
下划线 1.7.0
j查询 1.11.1

我有一个保存消息的集合。我的消息可以是不同的类型(并且每种类型的 api 中的端点都不同,但我有一个端点,允许我执行一个请求并获取所有消息)

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

我已经按照这里的建议进行了尝试:一个骨干.js多个模型子类的集合以及骨干文档 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 值只是一个大对象数组,所以如果不以某种方式遍历,这个解决方案对我来说毫无意义,而且很明显为什么它不起作用。

我是否正确处理了这个问题,还有其他方法可以做到这一点吗?

---更新----

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

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

因此,解决方案是混合使用模型函数和返回。

解释如下:

首先,我们有解析函数这只是我们更改从服务器收到的响应的入口点

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

在我的例子中,服务器返回一个对象的对象作为

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

首先,这很奇怪,显然需要解决。重要的一点是:当主干评估解析返回的响应时,它需要决定每个模型在哪里中断,就像定义新模型一样。

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

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

这是代码:

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

确定有更好的方法可以将对象解析为数组,但现在这有效,我又笑了!!

本文引导我找到解决方案:布偶的集合

您可以执行以下操作 - 对不同的类型做出反应(如果可能),然后提供不同的 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,则可以查看以下内容。

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