请注意,以下答案基于以下版本:
DEBUG: -------------------------------
ember.debug.js:5442DEBUG: Ember : 1.13.8
ember.debug.js:5442DEBUG: Ember Data : 1.13.9
ember.debug.js:5442DEBUG: jQuery : 1.11.3
DEBUG: -------------------------------
不幸的是,错误处理文档目前分散在各处,因为您处理不同适配器(Active、REST、JSON)的错误的方式都有些不同。
在您的情况下,您想要处理表单的验证错误,这可能意味着验证错误。JSON API 指定的错误格式可以在这里找到:http: //jsonapi.org/format/#error-objects
您会注意到,API 仅指定错误在以 by 为键的顶级数组中返回,errors
所有其他错误属性都是可选的。因此,似乎 JSON API 所需的一切如下:
{
"errors": [
{}
]
}
当然,这不会真正做任何事情,因此对于使用 Ember Data 和 JSONAPIAdapter 开箱即用的错误,您至少需要包含detail
属性和source/pointer
属性。该detail
属性是设置为错误消息的内容,该source/pointer
属性让 Ember Data 找出模型中的哪个属性导致了问题。因此,Ember Data 所需的有效 JSON API 错误对象(如果您使用的是现在默认的 JSONAPI)如下所示:
{
"errors": [
{
"detail": "The attribute `is-admin` is required",
"source": {
"pointer": "data/attributes/is-admin"
}
}
]
}
请注意,这detail
不是复数(对我来说是一个常见的错误),并且 for 的值source/pointer
不应包含前导正斜杠,并且属性名称应被虚化。
最后,您必须使用 HTTP 代码返回您的验证错误,422
这意味着“无法处理的实体”。如果您不返回422
代码,则默认情况下 Ember Data 将返回一个AdapterError
并且不会在模型的errors
哈希上设置错误消息。这让我有点苦恼,因为我使用 HTTP 代码400
(错误请求)将验证错误返回给客户端。
ember 数据区分这两种错误的方式是验证错误返回一个InvalidError
对象 ( http://emberjs.com/api/data/classes/DS.InvalidError.html )。这将导致errors
模型上的哈希被设置但不会将isError
标志设置为真(不知道为什么会这样,但它记录在这里:http ://emberjs.com/api/data/classes/DS.Model .html#property_isError)。默认情况下,HTTP 错误代码422
会导致AdapterError
返回一个并且isError
标志设置为true
. 在这两种情况下,promise 的拒绝处理程序都会被调用。
model.save().then(function(){
// yay! it worked
}, function(){
// it failed for some reason possibly a Bad Request (400)
// possibly a validation error (422)
}
默认情况下,如果返回的 HTTP 代码是 a422
并且您具有正确的 JSON API 错误格式,那么您可以通过访问模型的错误哈希来访问错误消息,其中哈希键是您的属性名称。哈希以驼峰格式键入属性名称。
例如,在我们上面的 json-api 错误示例中,如果出现错误,is-admin
您将访问该错误,如下所示:
model.get('errors.isAdmin');
这将返回一个包含错误对象的数组,格式如下:
[
{
"attribute": "isAdmin",
"message": "The attribute `is-admin` is required"
}
]
本质detail
上被映射到message
并被source/pointer
映射到attribute
. 如果您在单个属性上有多个验证错误,则会返回一个数组(JSON API 允许您返回多个验证错误,而不是只返回第一个验证失败)。您可以直接在模板中使用错误值,如下所示:
{{#each model.errors.isAdmin as |error|}}
<div class="error">
{{error.message}}
</div>
{{/each}}
如果没有错误,那么上面将不会显示任何内容,因此它可以很好地用于执行表单验证消息。
如果您的 API 不使用 HTTP422
代码来验证错误(例如,如果它使用),那么您可以通过覆盖自定义适配器中400
的方法来更改 JSONAPIAdapter 的默认行为。handleResponse
这是一个示例,它InvalidError
为任何 HTTP 响应状态代码返回一个新对象,即400
.
import DS from "ember-data";
import Ember from "ember";
export default DS.JSONAPIAdapter.extend({
handleResponse: function(status, headers, payload){
if(status === 400 && payload.errors){
return new DS.InvalidError(payload.errors);
}
return this._super(...arguments);
}
});
在上面的示例中,我正在检查 HTTP 状态是否为400
并确保存在错误属性。如果是这样,那么我创建一个新的DS.InvalidError
并返回它。这将导致与期望 HTTP 状态代码的默认行为相同的行为422
(即,将处理您的 JSON API 错误并将消息放入模型上的错误哈希中)。
希望有帮助!