21

我正在尝试将 Backbone 与 API 一起使用。

默认 API 响应格式为:

{
somemetadatas:xxx , 
results:yyy
}

无论是获取单个模型还是集合。

据我所知,我可以使用以下命令覆盖 Backboneparse函数:

parse: function (response) {
    return response.results;
},

但我在文档中看到:

解析 collection.parse(response)

每当服务器返回集合的模型时,Backbone 都会在 fetch 中调用parse 。该函数传递原始response对象,并应返回要添加到集合中的模型属性数组。默认实现是无操作的,只是通过 JSON 响应。如果您需要使用预先存在的 API 或更好的响应命名空间,请覆盖此选项。请注意,之后,如果您的模型类已经有一个parse函数,它将针对每个获取的模型运行。

因此,如果我对这样的集合提取有响应:

{
somemetadatas:xxx , 
results:[user1,user2]
}

集合上的第一个parse函数将提取[user1,user2].

但是医生说:

请注意,之后,如果您的模型类已经有一个parse函数,它将针对每个获取的模型运行。

所以它会尝试response.results;找到user1user2

我需要模型和集合上的解析函数,因为模型和集合数据都将在结果属性下。

但是,如果我获取一个集合,我不希望模型解析函数被用于单个数组元素。


那么有没有办法解决这个问题呢?

我想到了一个解决方案,我的集合解析函数将转换如下内容:

{
somemetadatas:xxx , 
results:[user1,user2]
}

变成这样的东西:

[ {results.user1} , {results.user2} ]

这样模型解析函数就不会在集合提取时失败。但这有点hacky......这个问题有什么优雅的解决方案吗?


顺便说一句,由于我的 API 总是会产生这种形式的结果,是否可以默认覆盖parse我所有模型和集合的功能?(对不起,我是一个 JS 菜鸟......)

4

2 回答 2

28

您可以测试您收到的数据是否由results成员包装并做出相应反应。例如,

var M = Backbone.Model.extend({
    parse: function (data) {
        if (_.isObject(data.results)) {
            return data.results;
        } else {
            return data;
        }
    }
});

还有一个小提琴http://jsfiddle.net/9rCH3/

如果你想概括这种行为,要么从这个基类派生你所有的模型类,要么修改 Backbone 的原型来提供这个功能:

Backbone.Model.prototype.parse = function (data) {
    if (_.isObject(data.results)) {
        return data.results;
    } else {
        return data;
    }
};

http://jsfiddle.net/9rCH3/1/

于 2012-08-13T17:15:37.860 回答
1

Parse 也必须在 Collection 中实现。

var EgCollection = Backbone.Collection.extend({
    parse: function (data) {
       if (_.isObject(data.results)) {
          return data.results;
       } else {
          return data;
       }
    }
});

http://backbonejs.org/#Collection-parse

于 2015-12-27T22:54:52.817 回答