我正在使用Backbone.js构建一个通常通过JSON与Web服务通信的应用程序。
一个Web服务会在成功时返回JSON,或者在错误中返回XML(聪明,是吧?)。我需要解析这个XML响应以确定错误,但Backbone的以JSON为中心的思想导致了我的问题。
我有一个包含解析功能的集合。当服务返回JSON时,总是调用parse函数,在这种情况下,我只返回响应对象。但是,当服务返回XML时,将调用我的fetch调用的错误回调函数,并传递arguments[1]
parseerror
的错误对象。进一步挖掘表明存在意外的<
字符。
为什么在抛出parseerror之前没有调用我的parse函数来解析XML?此外 - 为什么在成功的JSON调用中,它传递了一个JavaScript对象(表明JSON字符串已被解析)?是不是解析函数应该进行解析?
以下相关代码,任何建议都非常感谢。
var myCollection = Backbone.Collection.extend({
initialize : function() {
...
},
fetch: function(options) {
var options = {data: {...}, error: this.onFetchError};
Backbone.Collection.prototype.fetch.call(this, options);
},
onFetchError: function(arg1, arg2, arg3) {
debugger
},
parse: function(response) {
debugger
if(typeof response === 'object') {
return response;
}
}
});
return myCollection;
答案 0 :(得分:7)
文档对此很模糊。 Model.fetch([options])
使用Backbone.sync
。 docs for sync表示您可以使用“所有其他jQuery请求选项”,这意味着jQuery.ajax支持的任何内容。
因此,要将响应作为原始文本,您可以这样做:
this.fetch({ dataType: 'text' });
然后在parse
函数中,您可以根据需要处理响应。
旁注:在尝试获取模型以获取XML并使用该dataType进行测试时,我想到了这一点。
答案 1 :(得分:3)
如果你看一下默认的提取:
fetch: function(options) {
options = options ? _.clone(options) : {};
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
//-->parse only invoked on success
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp);
};
//-->parse not invoked on error
options.error = Backbone.wrapError(options.error, model, options);
return (this.sync || Backbone.sync).call(this, 'read', this, options);
}
您会发现在错误情况下永远不会调用解析。但是,wrapError(如下所示)将为您提供原始响应:
Backbone.wrapError = function(onError, originalModel, options) {
return function(model, resp) {
resp = model === originalModel ? resp : model;
if (onError) {
onError(originalModel, resp, options);
} else {
originalModel.trigger('error', originalModel, resp, options);
}
};
};
所以你的arg2会有响应,可以想象,你可以把它传递给你的解析函数。