这个问题是关于骨干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/xhr
和textStatus/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
正好等于originalModel
。resp
参数的目的是保存有关错误本身的信息。当出现 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);
}
};
};
* 表示从此处调用的错误回调