【发布时间】:2013-04-04 23:28:35
【问题描述】:
我正在使用 ember(+data) 并构建了一个简单的注册表单,但在服务器端验证错误后我无法让表单(和 ember-data 事务)正常工作。
我正在关注https://github.com/dgeb/ember_data_example 作为如何使用事务的指南,它主要适用于快乐路径,但是在服务器端验证错误之后,我无法获取 ember-data 来重新提交 API 请求当我点击提交时。
我做了一些挖掘,我认为我错过了一些与模型失效后重置事务相关的步骤或类似的东西......
Github 和应用程序
您可以在http://emb.herokuapp.com/尝试该应用并重现问题
您也可以在https://github.com/justinfaulkner/ember-data-resubmit查看完整的源代码
复制
您可以通过使用电子邮件地址 @example.com 在我的应用中填写表单来触发虚假的服务器端错误。 Rails API 将响应 422 和键入用户名/电子邮件字段的错误对象。
该字段应以红色突出显示并显示错误 - 将电子邮件地址编辑为应有效的内容,然后再次单击提交。在 chrome 中打开开发人员工具后,我看不到 ember-data 通过点击发送 http 请求(但控制器中的 console.log 表明确实收到了点击)。
应该发生什么
修改错误字段后,ember-data(我认为)将模型从invalid 更改为uncommitted,以便在下次调用commit 时提交。当我单击提交时,ember-data 应该将 HTTP 请求发送到我的 api,并且 ember 应该转换为“恭喜!”页面。
然而,表格只是坐在那里。没有http请求。没有过渡到“恭喜!”。
这是我在更新输入后单击提交几 (18) 次后的屏幕截图:
片段
以下是我的 ember 应用的一些 sn-ps:
索引路由
我的路线,它使用 startEditing,就像 ember_data_example 一样:
App.IndexRoute = Ember.Route.extend({
model: function() {
return null;
},
setupController: function(controller) {
controller.startEditing();
},
deactivate: function() {
this.controllerFor('index').stopEditing();
}
});
索引控制器
我的IndexController 仿照 ember_data_example 的ContactsNewController
App.IndexController = Ember.ObjectController.extend({
startEditing: function() {
this.transaction = this.get('store').transaction();
this.set('content', this.transaction.createRecord(App.User));
},
submit: function(user){
console.log("submitting!");
this.transaction.commit();
this.transaction = null;
},
_transitionOnSuccess: function(stuff) {
if (this.get('content.id') && this.get('content.id').length > 0) {
console.log("_transitionOnSuccess");
this.transitionToRoute('success');
}
}.observes('content.id'),
stopEditing: function() {
if (this.transaction) {
this.transaction.rollback();
this.transaction = null;
}
}
});
用户
这是我的模型。我正在使用ember-validations。
App.User = DS.Model.extend(Ember.Validations.Mixin);
App.User.reopen({
username: DS.attr('string'),
password: DS.attr('string'),
profile: DS.belongsTo('App.Profile'),
validations: {
username: {
presence: true
},
password: {
presence: true,
length: { minimum: 6 }
}
}
});
index.hbs
这是我的车把模板中的表格。我正在使用ember-easyForm。
{{#formFor controller}}
<div class="row">
<div class="large-12 columns">
{{input username placeholder="Email address"}}
</div>
</div>
<div class="row">
<div class="large-12 columns">
{{input password placeholder="Password"}}
</div>
</div>
{{submit "Sign Up" class="button"}}
{{/formFor}}
如果图书馆作者看到这篇文章,我在这个提交中对应用程序的 ember-easyForm 和 ember-validations 副本进行了一些本地修改:https://github.com/justinfaulkner/dockyard-example/commit/f618b0e4fb72314d56bb3a9d95e1325925ba6ad0。不过,我认为我的更改不会导致我的问题。
变得无效并回滚?
我确实在这里遇到了一个类似的问题:Ember Data and dirty records 但是当我添加一个User.becameInvalid 来回滚事务时,这会导致表单在尝试重新提交时为空(并且仍然没有成功获得 ember-数据重新提交http请求)。
谢谢!
我确定我对 ember_data_example 的关注很差(或者未能将其扩展到我的用例)或者在某处犯了一些简单的错误......
提前致谢。
4 月 5 日编辑
到目前为止,我至少可以发现两个主要问题:
-
this.transaction = null;我需要这个吗?我应该怎么做? - 我尝试删除
this.transaction = null;并且 ember-data 现在尝试实际提交(但仍然不会提交 ajax 请求)。现在,当我输入无效字段时,我可以看到 ember-data 尝试将记录更新回uncommitted/created... 但它在不同的事务中执行此操作。
我推了一个 no-null 分支到在 ember-data 中有一些 console.logs 的 repo,它打印出事务 ID 是什么......这是我的控制台的快照:
recordBecameDirty 在我输入字段时被调用。 Ember-data 更新记录以准备再次提交。但是,它是在其他一些事务中进行的 (458)
但我的提交按钮与原始事务 (316) 相关联,并且在该事务中没有准备好提交的记录....嗯....
【问题讨论】:
-
服务器返回错误后是否重新创建事务?我注意到您正在执行的初始提交:
this.transaction = null;我认为这会阻止任何后续请求通过(不过,我也希望控制台显示有关在 null 上调用 commit 的错误)。 -
除此之外,我注意到,当服务器返回错误时,模型会进入错误状态,并且模型状态机似乎没有提供错误状态的转换(这在为了尝试再次保存模型)。 This stackoverflow post 被证明是非常有帮助的(尽管我认为修复似乎更像是解决 ember-data 错误的方法)。
-
我认为模型在某些时候会转移到不同的事务中。此外,当我输入错误字段时,我认为 ember-data 会注意到字段更改并自动将其转换为错误状态。我会检查这两项声明,以确保我没有搞混。
标签: ember.js