在使用Ember.js数据RESTAdapter时应如何处理错误?

ember-data.js: https : //github.com/emberjs/data/tree/0396411e39df96c8506de3182c81414c1d0eb981

总之,当出现错误时,我想在视图中显示错误消息,然后用户可以1)取消,这将回滚事务2)纠正input错误并成功提交事务,通过validation服务器。

以下是源代码片段。 它不包含错误callback。

updateRecord: function(store, type, record) { var id = get(record, 'id'); var root = this.rootForType(type); var data = {}; data[root] = this.toJSON(record); this.ajax(this.buildURL(root, id), "PUT", { data: data, context: this, success: function(json) { this.didUpdateRecord(store, type, record, json); } }); }, 

总体而言,从服务器接收错误并更新视图的stream程是什么? 看起来,错误callback应该把模型置于isError状态,然后视图可以显示相应的消息。 此外,交易应该保持肮脏。 这样,事务可以使用rollback

看来,使用store.recordWasInvalid是朝着正确的方向,虽然。

这个周末我正在试图找出同样的事情。 走出卢克所说的,我仔细看了一下最新的提交 (12月11日)的烬数据源。

TLDR; 要处理ember-data更新/创build错误,只需在您的DS.Model实例上定义becameError()becameInvalid(errors) DS.Model 由RESTadapter的AJAX错误callback触发的级联最终将调用您定义的这些函数。

例:

 App.Post = DS.Model.extend title: DS.attr "string" body: DS.attr "string" becameError: -> # handle error case here alert 'there was an error!' becameInvalid: (errors) -> # record was invalid alert "Record was invalid because: #{errors}" 

以下是源代码的完整步骤:

在REST适配器中,AJAXcallback错误函数在这里给出:

  this.ajax(this.buildURL(root, id), "PUT", { data: data, context: this, success: function(json) { Ember.run(this, function(){ this.didUpdateRecord(store, type, record, json); }); }, error: function(xhr) { this.didError(store, type, record, xhr); } }); 

didError是在这里定义的,它依次调用存储的recordWasInvalid或recordWasError,具体取决于响应:

  didError: function(store, type, record, xhr) { if (xhr.status === 422) { var data = JSON.parse(xhr.responseText); store.recordWasInvalid(record, data['errors']); } else { store.recordWasError(record); } }, 

反过来, store.recordWasInvalidstore.recordWasError ( 在这里定义)调用logging(DS.Model)的处理程序。 在无效的情况下,它将来自适配器的错误消息作为parameter passing。

  recordWasInvalid: function(record, errors) { record.adapterDidInvalidate(errors); }, recordWasError: function(record) { record.adapterDidError(); }, 

DS.Model.adapterDidInvalidateadapterDidError (定义在这里 )只是send('becameInvalid', errors)send('becameError') ,最终引导我们到这里的处理程序:

  didLoad: Ember.K, didUpdate: Ember.K, didCreate: Ember.K, didDelete: Ember.K, becameInvalid: Ember.K, becameError: Ember.K, 

(Ember.K只是一个虚拟的函数来返回this

所以,结论是,你只需要在你的模型中定义函数becameInvalidbecameError来处理这些情况。

希望这可以帮助别人; 该文件当然不反映这个权利。

DS.RESTAdapter在这个提交中只是得到了更多的error handling,但是我们仍然没有很好地推荐error handling。

如果你有足够的野心/疯狂地把应用程序放在今天的产品中(像我一样!),最好确保你的API失败的可能性非常低。 即validation你的数据客户端。

希望在接下来的几个月里能更好地回答这个问题。

我只是遇到了这样的情况,不知道这是否已经在任何地方解释。

我在用:

 Em.VERSION : 1.0.0 DS.VERSION : "1.0.0-beta.6" Ember Validations (dockyard) : Version: 1.0.0.beta.1 Ember I18n 

该模型最初与Validation mixin混合。

 App.Order = DS.Model.extend(Ember.Validations.Mixin, { ..... someAttribute : DS.attr('string'), /* Client side input validation with ember-validations */ validations : { someAttribute : { presence : { message : Ember.I18n.t('translations.someAttributeInputError') } } } }); 

在模板中,添加相应的句柄。 (注意,在inputvalidation的情况下,embervalidation会自动将错误添加到model.errors.<attribute>中,我也将在服务器validation中使用相同的权衡)

 <p>{{t 'translations.myString'}}<br> {{view Ember.TextField valueBinding="attributeName"}} {{#if model.errors.attributeName.length}}<small class="error">{{model.errors.attributeName}}</small>{{/if}} </p 

现在,我们将保存Order

 App.get('order').save().then(function () { //move to next state? }, function(xhr){ var errors = xhr.responseJSON.errors; for(var error in errors){ //this loop is for I18n errors[error] = Ember.I18n.t(errors[error]); } controller.get('model').set('errors', errors); //this will overwrite current errors if any }); 

现在,如果从服务器抛出一些validation错误,正在使用的返回的数据包是

 {"errors":{"attributeName1":"translations.attributeNameEror", "another":"translations.anotherError"}} status : 422 

使用状态422很重要

所以这样,你的属性可以在客户端和服务器端validation。

免责声明:我不确定这是否是最好的方法!

由于目前股票Ember-Data没有很好的解决scheme,我通过向apiErrors添加apiErrors属性,然后在RestAdapter子类(我已经需要我自己的)中创build了自己的解决scheme,并向Ajax调用createRecord添加了错误callback函数, updateRecord保存错误并将模型置于“无效”状态,这意味着客户端或服务器端validation失败。

以下是代码片段:

这可以在application.js或其他一些顶级文件中进行:

 DS.Model.reopen({ // Added for better error handling on create/update apiErrors: null }); 

这在RestAdapter子类中的createRecordupdateRecord的错误callback中进行:

 error: function(xhr, textStatus, err) { console.log(xhr.responseText); errors = null; try { errors = JSON.parse(xhr.responseText).errors; } catch(e){} //ignore parse error if(errors) { record.set('apiErrors',errors); } record.send('becameInvalid'); }