Joh*_*ika 12 ember.js ember-data
我正在使用Ember Data,我似乎无法获得模型的'errors'属性来填充来自我的REST API的错误消息.我非常关注本指南中的示例:
http://emberjs.com/api/data/classes/DS.Errors.html
我的应用程序如下所示:
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();
}
}
});
Run Code Online (Sandbox Code Playgroud)
我的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."]
}
}
Run Code Online (Sandbox Code Playgroud)
在模型上调用save()后,我在用户模型上看到的是:
user.get('isError') // true
user.get('errors.messages') // []
Run Code Online (Sandbox Code Playgroud)
即使模型正确地注册了isError属性,我也似乎无法填充错误消息.我怎样才能让它发挥作用?我正在研究Ember Data版本1.0.0-beta.8.2a68c63a的最新beta版本
Kin*_*n2k 10
这个区域肯定缺少文档,除非您使用的是活动模型适配器,否则不会填充错误.
这是一个工作的例子,也看看Ember:error.messages在保存时没有显示服务器错误我在说同样的事情
http://jsbin.com/motuvaye/24/edit
您可以通过覆盖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;
}
}
});
Run Code Online (Sandbox Code Playgroud)
http://jsbin.com/motuvaye/27/edit
我对Ember Data的errors.messages属性有过长期非常令人沮丧的经历,所以我想我总结了我的所有发现,以防其他人试图使用这个功能.
1)文档已过期
正如@ kingpin2k在他的回答中提到的那样,http : //emberjs.com/api/data/classes/DS.Errors.html上的文档已经过时了.他们在该页面上提供的示例仅在您使用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.' });
}
});
Run Code Online (Sandbox Code Playgroud)
2)您必须提供拒绝回调
这很奇怪,但是当你在你的模型上调用save()时,你需要提供一个拒绝回调,否则,你将得到一个未被捕获的'后端拒绝提交'异常,JavaScript将停止执行.我不知道为什么会这样.
没有拒绝回调的示例.这将导致异常:
user.save().then(function (model) {
// do something
});
Run Code Online (Sandbox Code Playgroud)
拒绝回调的示例.一切都会运作良好:
user.save().then(function (model) {
// do something
}, function (error) {
// must supply reject callback, otherwise Ember will throw a 'backend rejected the commit' error.
});
Run Code Online (Sandbox Code Playgroud)
3)默认情况下,只有作为模型一部分的错误属性才会在errors.messages中注册. 例如,如果这是您的模型:
App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string')
});
Run Code Online (Sandbox Code Playgroud)
...如果这是你的错误有效载荷:
{
"errors": {
"firstName":"is required",
"summary":"something went wrong"
}
}
Run Code Online (Sandbox Code Playgroud)
然后摘要不会出现在user.get('errors.messages')中.可以在Ember Data的adapterDidInvalidate方法中找到此问题的根源.它使用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);
}
Run Code Online (Sandbox Code Playgroud)
这里有关于这个问题的讨论:https://github.com/emberjs/data/issues/1877
在Ember团队修复此问题之前,您可以通过创建一个覆盖默认的adapterDidInvalidate实现的自定义基本模型来解决此问题,并且所有其他模型都从中继承:
基本型号:
App.Model = DS.Model.extend({
adapterDidInvalidate: function (errors) {
var recordErrors = this.get('errors');
Ember.keys(errors).forEach(function (key) {
recordErrors.add(key, errors[key]);
});
}
});
Run Code Online (Sandbox Code Playgroud)
用户模型:
App.User = App.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string')
});
Run Code Online (Sandbox Code Playgroud)
4)如果从适配器的ajaxError(我们上面覆盖的那个)返回DS.InvalidError,那么你的模型将停留在'isSaving'状态,你将无法摆脱它.
如果您使用DS.ActiveModelAdapter,也会出现此问题.
例如:
user.deleteRecord();
user.save().then(function (model) {
// do something
}, function (error) {
});
Run Code Online (Sandbox Code Playgroud)
当服务器响应错误时,模型的isSaving状态为true,我无法在不重新加载页面的情况下重置它.
更新:2014-10-30 对于那些正在努力解决DS.Errors的人来说,这里有一篇很好的博客文章,总结了这一点:http://alexspeller.com/server-side-validations-with-ember-data-and-ds- 错误/
| 归档时间: |
|
| 查看次数: |
5091 次 |
| 最近记录: |