我使用的是Ember 1.13.7和Ember Data 1.13.8,它默认使用JSON-API标准来格式化发送到API和从API接收的有效负载。
我想使用Ember Data的内置错误处理来显示红色"错误"向用户表单字段。我根据JSON-API标准格式化了我的API错误响应,例如
{"errors":[
{
"title":"The included.1.attributes.street name field is required.",
"code":"API_ERR",
"status":"400",
}
]}
当我尝试保存模型时,正确执行错误回调。如果我在Ember Inspector中查看,我可以看到模型" s" isError" value设置为true但是我无法看到Ember Data如何知道模型中哪个字段是错误状态的字段?我从官方的JSON-API页面(http://jsonapi.org/format/#errors)中看到,您可以包含一个"来源"错误响应中的对象:
source:包含对错误源的引用的对象, 可选择包括以下任何成员:
指针:请求文档中关联实体的JSON指针[RFC6901] [例如。 " /数据"对于主要数据对象,或者" / data / attributes / title" 对于特定属性]。
参数:表示哪个查询的字符串 参数导致错误。
但这是我应该做的,以便告诉Ember Data它应该标记哪些字段处于错误状态?
如果有人能帮助阐明这一点,我将不胜感激。
感谢。
答案 0 :(得分:86)
请注意,以下答案基于以下版本:
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仅指定在由errors
键入的顶级数组中返回错误,并且所有其他错误属性都是可选的。所以看起来JSON API需要的是以下内容:
{
"errors": [
{}
]
}
当然,实际上并没有做任何事情因此,如果错误与Ember Data和JSONAPIAdapter一起开箱即用,您至少需要包含detail
属性和{{1} }属性。 source/pointer
属性被设置为错误消息,detail
属性允许Ember Data确定模型中的哪个属性导致问题。因此,Ember Data要求的有效JSON API错误对象(如果您正在使用现在默认的JSONAPI)是这样的:
source/pointer
请注意{
"errors": [
{
"detail": "The attribute `is-admin` is required",
"source": {
"pointer": "data/attributes/is-admin"
}
}
]
}
不是复数(对我来说是一个常见的错误),detail
的值不应包含前导斜杠,属性名称应该是dasherized。
最后,您必须使用HTTP代码source/pointer
返回验证错误,这意味着" Unprocessable Entity"。如果您未返回422
代码,则默认情况下,Ember Data将返回422
,并且不会在模型的AdapterError
哈希上设置错误消息。这让我有点困难,因为我使用HTTP代码errors
(错误请求)将验证错误返回给客户端。
ember数据区分两种类型错误的方式是验证错误返回400
对象(http://emberjs.com/api/data/classes/DS.InvalidError.html)。这将导致设置模型上的InvalidError
哈希值,但不会将errors
标志设置为true(不确定为什么会出现这种情况,但在此处记录:http://emberjs.com/api/data/classes/DS.Model.html#property_isError)。默认情况下,除isError
以外的HTTP错误代码将导致返回422
并将AdapterError
标记设置为isError
。在这两种情况下,都会调用promise的拒绝处理程序。
true
默认情况下,如果返回的HTTP代码是model.save().then(function(){
// yay! it worked
}, function(){
// it failed for some reason possibly a Bad Request (400)
// possibly a validation error (422)
}
并且您具有正确的JSON API错误格式,那么您可以通过访问模型的错误哈希来访问错误消息,其中哈希键是您的属性名。哈希以camelcase格式键入属性名称。
例如,在我们上面的json-api错误示例中,如果422
上出现错误,您将会像这样访问该错误:
is-admin
这将返回一个包含错误对象的数组,其格式如下:
model.get('errors.isAdmin');
基本上[
{
"attribute": "isAdmin",
"message": "The attribute `is-admin` is required"
}
]
映射到detail
,message
映射到source/pointer
。如果您在单个属性上有多个验证错误,则返回一个数组(JSON API允许您返回多个验证错误,而不是仅返回第一个验证失败)。您可以直接在模板中使用错误值,如下所示:
attribute
如果没有错误,那么上面的内容不会显示任何内容,因此它可以很好地用于表单验证消息。
如果您的API不使用HTTP {{#each model.errors.isAdmin as |error|}}
<div class="error">
{{error.message}}
</div>
{{/each}}
代码进行验证错误(例如,如果它使用422
),那么您可以通过覆盖400
来更改JSONAPIAdapter的默认行为自定义适配器中的方法。下面是一个示例,它为handleResponse
的任何HTTP响应状态代码返回一个新的InvalidError
对象。
400
在上面的示例中,我检查HTTP状态是否为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);
}
});
并确保存在errors属性。如果是,那么我创建一个新的400
并返回。这将导致与期望DS.InvalidError
HTTP状态代码的默认行为相同的行为(即,将处理您的JSON API错误并将消息放入模型中的错误哈希)。
希望有所帮助!