Javascript 覆盖主干的解析函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11938500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overriding backbone's parse function
提问by Sebastien Lorber
I'm trying to use Backbone with an API.
我正在尝试将 Backbone 与 API 一起使用。
The default API response format is:
默认的 API 响应格式为:
{
somemetadatas:xxx ,
results:yyy
}
Whether it's a fetch for a single model or a collection.
无论是获取单个模型还是集合。
So as far as I know I can override the Backbone parse
function with:
因此,据我所知,我可以使用以下命令覆盖 Backboneparse
函数:
parse: function (response) {
return response.results;
},
But I've seen in the documentation:
但我在文档中看到:
parse
collection.parse(response)
parseis called by Backbone whenever a collection's models are returned by the server, in fetch. The function is passed the raw
response
object, and should return the array of model attributes to be added to the collection. The default implementation is a no-op, simply passing through the JSON response. Override this if you need to work with a preexisting API, or better namespace your responses. Note that afterwards, if your model class already has aparse
function, it will be run against each fetched model.
解析
collection.parse(response)
每当服务器在 fetch 中返回集合的模型时,Backbone 都会调用parse。该函数传递原始
response
对象,并应返回要添加到集合中的模型属性数组。默认实现是无操作,只是传递 JSON 响应。如果您需要使用预先存在的 API 或更好的命名空间您的响应,请覆盖它。请注意,之后,如果您的模型类已经有一个parse
函数,它将针对每个获取的模型运行。
So if I have a response for a collection fetch like that:
因此,如果我对这样的集合获取有响应:
{
somemetadatas:xxx ,
results:[user1,user2]
}
The first parse
function on the collection will extract [user1,user2]
.
parse
集合上的第一个函数将提取[user1,user2]
.
But the doc says:
但是医生说:
Note that afterwards, if your model class already has a
parse
function, it will be run against each fetched model.
请注意,之后,如果您的模型类已经有一个
parse
函数,它将针对每个获取的模型运行。
So it will try to find response.results;
on user1
and user2
所以它会试图找到response.results;
在user1
和user2
I need both parse functions on the model and collection because both model and collection datas will be under the result attribute.
我需要模型和集合上的解析函数,因为模型和集合数据都在结果属性下。
But if i fetch on a collection, I don't want the model parse function to be used againt a single array element.
但是如果我获取一个集合,我不希望模型解析函数再次用于单个数组元素。
So is there a solution to this problem?
那么有没有办法解决这个问题呢?
I think of a solution where my collection parse function will transform something like this:
我想到了一个解决方案,我的集合解析函数将转换如下:
{
somemetadatas:xxx ,
results:[user1,user2]
}
into something like this:
变成这样:
[ {results.user1} , {results.user2} ]
So that the model parse function will not fail on a collection fetch. But it's a bit hacky... is there any elegant solution to this problem?
这样模型解析函数就不会在集合获取时失败。但这有点hacky......这个问题有什么优雅的解决方案吗?
By the way, as my API will always produce results of this form, is it possible to override by default the parse
function of all my models and collections? (Sorry i'm a JS noob...)
顺便说一下,由于我的 API 总是会产生这种形式的结果,是否可以默认覆盖parse
我所有模型和集合的功能?(对不起,我是一个 JS 菜鸟...)
回答by nikoshr
You could test if the data you receive is wrapped by a results
member and react accordingly. For example,
您可以测试您收到的数据是否由results
成员包装并做出相应的反应。例如,
var M = Backbone.Model.extend({
parse: function (data) {
if (_.isObject(data.results)) {
return data.results;
} else {
return data;
}
}
});
And a Fiddle http://jsfiddle.net/9rCH3/
还有一个小提琴http://jsfiddle.net/9rCH3/
If you want to generalize this behavior, either derive all your model classes from this base class or modify Backbone's prototype to provide this function :
如果你想概括这个行为,要么从这个基类派生所有的模型类,要么修改 Backbone 的原型来提供这个函数:
Backbone.Model.prototype.parse = function (data) {
if (_.isObject(data.results)) {
return data.results;
} else {
return data;
}
};
回答by Thomee
Parse also must be implemented in the Collection.
Parse 也必须在 Collection 中实现。
var EgCollection = Backbone.Collection.extend({
parse: function (data) {
if (_.isObject(data.results)) {
return data.results;
} else {
return data;
}
}
});