Backbone.js Backbone.wrapError function



这个问题是关于骨干0.9.2

自从升级到Backbone 0.9.10以来,我们选择覆盖Backbone.sync,它就像一个魅力。

  • 2012 年 12 月 - (v0.9.9( 已删除 Backbone.wrapError。
  • 2013 年 2 月 - 看起来 WrapError 将在下一版本的 Backbone 中恢复,但覆盖 backbone.sync 是要走的路。

(抱歉阅读时间过长(

我正在修改 Backbone.wrapError 函数,我被一行弄糊涂了。我知道这条线是做什么的,但不知道为什么它是必要的。

  resp = model === originalModel ? resp : model;
  • resp 最终成为 textStatus/errorType,即:"error" "timeout"解析错误">
  • 模型是 XHR 请求对象
  • originalModel 是对 Backbone.Model 实例的引用,该实例最终调用了此函数。

我很好地掌握了 Backbone.wrapError 的作用、它返回的内容以及它的使用方式,但我似乎无法理解上述行的目的。


Backbone的文档指出wrapError将"用回退错误事件包装可选的错误回调",这是真的。此外,我了解到 Backbone.wrapError 在库中从获取、保存、销毁和重置函数中调用了 4 次,以确保库不会忽视 AJAX 错误。例如,如果将 AJAX 错误回调传递到 fetch 方法中,它将在传递几个参数的情况下执行,否则,模型将使用传递的相同几个参数触发错误事件。

示例调用:

options.error = Backbone.wrapError(options.error, model, options);

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

这一行(resp = model === originalModel ? resp : model;(产生的问题是模型和resp对应于jQuery/Zepto错误回调参数列表中的前2个参数。我遇到的第一个问题是这些参数(模型、响应(的命名,因为在调试时,我已经看到这两个参数是jqXHR/xhrtextStatus/errorType的。textStatus/errorType 参数通常最终是"错误",但(根据文档(也可以是"超时"、"解析错误"等。model === originalModel的比较对我来说毫无意义。对 XHR 对象和 Backbone.Model 实例进行硬比较总是会失败,model将被存储到 response (resp( 中,这很好,因为model实际上是 XHR 响应对象......这一行对我来说似乎毫无意义,但我继续将其包含在我修改后的 wrapError 方法中。

因为model === originalModel总是计算为 false,所以该行似乎是 resp = model 的复杂版本;这是没有用的,因为您可以完全删除该行,并且 model 参数可以传递到 originalModel.trigger('error', originalModel, resp, options); 而不是 resp 中。

是否有任何实例可以model === originalModel评估为真?

任何在 Backbone.js、AJAX 方面有更多经验的人都有答案/解释为什么这条线是必要的?

TLDR/CLIFFS:

下面奇怪的小行用于确定错误回调是由模型级别的失败验证触发的,或者来自获取、保存或销毁方法(都调用 Backbone.sync(的失败 AJAX 调用触发的天气。如果失败来自验证,则不会更改 resp 变量,因为 resp 应该已经包含验证返回的有用信息(例如错误数组或有关错误的字符串(。如果失败来自错误的 AJAX 请求,则 XHR 对象将存储到 resp 中,因为 XHR 是可用的信息量最大的项目。不幸的是,XHR作为模型传递到此函数中,并且Backbone文档未能指出此参数并不总是代表模型。Resp 旨在保存有关错误的有用响应信息,并发送到错误回调或引发的错误事件。


好。我从这条奇怪的台词中学到了一些东西。

resp = model === originalModel ? resp : model;

在主干中存在 AJAX 错误和验证错误。方便的是,Backbone将两个错误汇集到同一个函数中 - AJAX错误回调。问题是传递给这些函数的参数不一致。当出现 AJAX 错误时,XHR 对象可用,但在验证错误期间不可用。

  • 如果不存在回调,Backbone 将抛出"error"事件,其参数与传入错误回调的参数相同。(下面的第 7 行和第 9 行(。

成功发出 AJAX 请求后,可以选择通过模型的验证函数传递 JSON 数据。在主干网中,验证函数should return false or nothing at all when there are no errors 。当存在错误时,通常返回一个数组,例如 ['invalid username', 'password too long', 'etc...'] 从 validate 返回的任何内容(通常是错误消息数组(都作为 resp 参数传递到"包装"错误回调中,模型本身作为model传递

_validate函数有点草率,有多个返回语句,但是当验证失败时,会命中第 9 行。_validate函数的第 9 行传递this(模型(、error(从模型验证方法返回(、options(ajax 选项、成功、错误、超时等(。这与 AJAX 错误不同,AJAX 错误将在xhr(xmlhttprequest 对象(、errorType("错误"、"超时"、"解析错误"等(options(ajax 选项(中传递。

validate error:   error(model, validate_return_value, options)
    ajax error:   error(xhr, errorType, options)
1   _validate: function(attrs, options) {
2     if (options.silent || !this.validate) return true;
3     attrs = _.extend({}, this.attributes, attrs);
4     var error = this.validate(attrs, options);
5     if (!error) return true;
6     if (options && options.error) {
7*       options.error(this, error, options);
8     } else {
9       this.trigger('error', this, error, options);
10    }
11    return false;
12  }

上面奇怪的代码行是必要的,因为这个函数处理来自 2 种不同方法的错误。AJAX 和验证。这 2 个向其发送不同的参数,因此这意味着规范化它们并使用一致的参数列表抛出事件。

When a validation error occurs, the model does not change,因此传递到错误回调中的model正好等于originalModelresp参数的目的是保存有关错误本身的信息。当出现 AJAX 错误时,"超时"、"解析错误"或"错误"根本不像 XHR 对象那样提供信息。

这个奇怪的小行决定了错误回调是从_validate或通过正常的 AJAX 错误(如 404(访问的。从验证访问它时,resp是从验证返回的值。它应该是信息丰富的,并且对前端模板显示有用的数据。当生成的错误来自 HTTP 错误时,有关该错误的最有用信息是作为 MODEL 参数传递到此函数的 XHR 对象。

希望简化的包装错误和验证函数的方法

   Backbone.wrapError = function(ajax_error_callback, model_or_xhr, ajax_options) {
      return function(model_or_xhr, error_info) {
        if there was an ajax error, error_info = the xhr object
        if there was a validation error, error_info = whatever was returned from validate
        if there's an error callback {
          run the error callback with (the original model, error_info, ajax_options)  as parameters
        if there is not an error callback
          throw an event called 'error' with (the original model, error_info, ajax_options) as parameters
        }
      };
    };

源语言:

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

* 表示从此处调用的错误回调

最新更新