带有XML响应的Backbone.js - 在解析错误之前未调用解析函数

时间:2012-05-24 19:55:12

标签: xml ajax parsing backbone.js

我正在使用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;

2 个答案:

答案 0 :(得分:7)

文档对此很模糊。 Model.fetch([options])使用Backbone.syncdocs 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会有响应,可以想象,你可以把它传递给你的解析函数。