Ember.js 余烬数据模型';s errors属性(DS.errors)未填充
我使用的是余烬数据,似乎无法使用RESTAPI中的错误消息填充模型的“errors”属性。我基本上遵循了本指南中的示例: 我的应用程序如下所示:Ember.js 余烬数据模型';s errors属性(DS.errors)未填充,ember.js,ember-data,Ember.js,Ember Data,我使用的是余烬数据,似乎无法使用RESTAPI中的错误消息填充模型的“errors”属性。我基本上遵循了本指南中的示例: 我的应用程序如下所示: window.App = Ember.Application.create(); App.User = DS.Model.extend({ username: DS.attr('string'), email: DS.attr('string') }); App.Applicatio
window.App = Ember.Application.create();
App.User = DS.Model.extend({
username: DS.attr('string'),
email: DS.attr('string')
});
App.ApplicationRoute = Ember.Route.extend({
model: function () {
return this.store.createRecord('user', {
username: 'mike',
email: 'invalidEmail'
});
},
actions: {
save: function () {
this.modelFor(this.routeName).save();
}
}
});
我的API返回以下内容:
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 125
{
"errors": {
"username": ["Username is taken!"],
"email": ["Email is invalid."]
}
}
在模型上调用save()后,我在用户模型上看到了以下内容:
user.get('isError') // true
user.get('errors.messages') // []
App.User = App.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string')
});
即使模型正确地注册了isError属性,我似乎也无法获得要填充的错误消息。我怎样才能让它工作?我正在开发Ember数据版本1.0.0-beta.8.2a68c63a的最新beta版。这方面的文档肯定没有,除非使用活动模型适配器,否则不会填充错误 这里有一个例子,它的工作,也看看我说同样的事情 通过覆盖
ajaxError
并复制活动模型适配器的操作方式,您可以相当轻松地在RESTAdapter上实现它
App.ApplicationAdapter = DS.RESTAdapter.extend({
ajaxError: function(jqXHR) {
var error = this._super(jqXHR);
if (jqXHR && jqXHR.status === 422) {
var response = Ember.$.parseJSON(jqXHR.responseText),
errors = {};
if (response.errors !== undefined) {
var jsonErrors = response.errors;
Ember.EnumerableUtils.forEach(Ember.keys(jsonErrors), function(key) {
errors[Ember.String.camelize(key)] = jsonErrors[key];
});
}
return new DS.InvalidError(errors);
} else {
return error;
}
}
});
我对余烬数据的errors.messages属性有一段漫长而令人沮丧的经历,因此我想在此总结一下我的所有发现,以防其他人尝试使用此功能 1)文档已过时 正如@kingpin2k在其回答中提到的,处的文档已过时。只有在使用DS.ActiveModelAdapter时,它们在该页面上提供的示例才有效。如果您使用的是默认的DS.RESTAdapter,那么您需要执行类似的操作。请注意,我更喜欢这种更简单的方法,而不是复制ActiveModelAdapter的ajaxError实现:
App.ApplicationAdapter = DS.RESTAdapter.extend({
ajaxError: function (jqXHR) {
this._super(jqXHR);
var response = Ember.$.parseJSON(jqXHR.responseText);
if (response.errors)
return new DS.InvalidError(response.errors);
else
return new DS.InvalidError({ summary: 'Error connecting to the server.' });
}
});
2)您必须提供拒绝回调
这很奇怪,但是当您在模型上调用save()时,您需要提供拒绝回调,否则,您将得到一个未捕获的“backend rejected the commit”异常,JavaScript将停止执行。我不知道为什么会这样
没有拒绝回调的示例。这将导致异常:
user.save().then(function (model) {
// do something
});
拒绝回调的示例。一切都会顺利进行:
user.save().then(function (model) {
// do something
}, function (error) {
// must supply reject callback, otherwise Ember will throw a 'backend rejected the commit' error.
});
3)默认情况下,只有作为模型一部分的错误属性才会在错误消息中注册。例如,如果这是您的模型:
App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string')
});
…如果这是您的错误负载:
{
"errors": {
"firstName":"is required",
"summary":"something went wrong"
}
}
然后摘要将不会出现在user.get('errors.messages')中。这个问题的根源可以在Ember数据的AdapterDidValidate方法中找到。它使用this.eachAttribute和this.eachRelationship将错误消息的注册限制为仅属于模型一部分的错误消息
adapterDidInvalidate: function(errors) {
var recordErrors = get(this, 'errors');
function addError(name) {
if (errors[name]) {
recordErrors.add(name, errors[name]);
}
}
this.eachAttribute(addError);
this.eachRelationship(addError);
}
这里有一个关于这个问题的讨论:
在Ember团队解决此问题之前,您可以通过创建一个覆盖默认AdapterDidValidate实现的自定义基础模型来解决此问题,并且您的所有其他模型都从中继承:
基本型号:
App.Model = DS.Model.extend({
adapterDidInvalidate: function (errors) {
var recordErrors = this.get('errors');
Ember.keys(errors).forEach(function (key) {
recordErrors.add(key, errors[key]);
});
}
});
用户模型:
user.get('isError') // true
user.get('errors.messages') // []
App.User = App.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string')
});
4)如果您从适配器的ajaxError返回DS.InvalidError(我们在上面覆盖的错误),那么您的模型将处于“正在保存”状态,您将无法摆脱它。
如果使用DS.ActiveModelAdapter,也会出现此问题
例如:
user.deleteRecord();
user.save().then(function (model) {
// do something
}, function (error) {
});
当服务器响应错误时,模型的isSaving状态为true,我无法在不重新加载页面的情况下重置它
更新:2014-10-30
对于那些正在与DS.Errors作斗争的人来说,这里有一篇很好的博文总结了这一点:更新:Ember Data 2.x 上面的回答仍然有一定的相关性,通常非常有用,但现在对于Ember Data 2.x(撰写本文时为v2.5.1)来说已经过时了。使用较新版本的余烬数据时,请注意以下几点:
在2.x中不再具有DS.RESTAdapter
功能。这件事现在由我们来处理。如果需要对错误进行任何特殊处理或格式化,则可以重写此方法李>ajaxError
- 关于
和DS.Errors
(这是DS.Errors的一个实例)的文档目前有点误导。它仅在响应中的错误符合JSON API错误对象规范时才起作用。这意味着,如果您的API错误对象遵循任何其他格式,那么它将毫无用处。不幸的是,这个行为目前不能像Ember数据中的许多其他东西一样被覆盖,因为这个行为是在DS.Model中Ember的InternalModel类的私有API中处理的DS.Model.Errors
仅在响应状态代码默认为DS.InvalidError
时使用。如果您的API使用不同的状态代码来表示无效请求的错误,您可以重写422
,以自定义要检查的状态代码(或错误响应的其他部分)以表示RESTAdapter.isInvalid()
InvalidError
- 作为替代方法,您可以覆盖
以始终返回false,这样余烬数据将始终创建更通用的。然后在DS.Model.adapterError上设置此错误,并可根据需要从那里利用此错误isInvalid()
包含API响应的DS.AdapterError.errors
键上返回的内容errors