21

我正在努力理解将在以下场景中使用的工作流程:

用户创建一个模型,我们称之为产品。我们向他们展示了一个要填写的表单。由于验证以外的某些原因(超时、访问被拒绝等)而导致的保存错误在 Ember 中,这会将模型置于错误状态。从 UI 的角度来看,我要做的就是在屏幕上显示一条消息(简单)并允许用户再试一次(显然不是那么容易)。

我已经多次看到它不重用事务。我明白其中的逻辑。在新产品的情况下,我简单地创建另一个新产品,合并来自原始产品的数据(属性、关系)并用新产品替换我的控制器的内容。这并不难,而且看起来效果很好,尽管可能(希望)有更好的方法。

但是,当我编辑产品时,我遇到了一个严重的问题,上述解决方案不起作用。产品模型现在处于错误状态,我找不到任何方法来获取该产品的副本,该副本也不处于相同状态。

我无法弄清楚的是,一旦该模型达到错误状态,我可以用它做什么。我尝试了以下方法:

回滚:这不起作用。您不能回滚处于错误状态的事务。

重新加载:同上。不允许在错误状态下重新加载记录。

获取记录的新副本:所以我尝试使用与现有记录相同的 ID 的 App.Product.find(id)。它只是给了我一份现有记录的副本,处于错误状态。

我希望我在这里遗漏了一些相当基本的东西。是否可以将记录很好地从错误状态(或无效状态)中推出?

如果有一种简单的方法可以改变这些模型的状态,我们是否还应该创建一个新事务来进一步尝试提交?

4

4 回答 4

14

因此,经过几天的阅读源代码和实验,我得出的结论是,这是尚未实现的功能。要将记录移动到另一个状态,您应该向它发送一个事件,该事件在statemanager. 似乎没有在错误状态上注册的事件允许我们恢复记录。

有一个丑陋的解决方法 - 我可以调用transitionTo记录statemanager并强制它进入我们想要的状态。我并没有轻易决定这样做,但在这一点上,我必须在等待 ember-data 发展的同时继续该项目。因此,如果记录到目前为止尚未保存,我们可以通过调用将其从无效或错误状态中拯救出来:

model.get('stateManager').transitionTo('loaded.created.uncommitted')

或对于现有记录:

model.get('stateManager').transitionTo('loaded.updated')

一旦调用了它,您就可以尝试在模型所在的事务上再次调用 commit。这将是默认事务,因为 ember-data 的行为是在调用 commit 后将模型移动到默认事务中这是原始交易。您始终可以通过调用来检索模型的当前事务model.get('transaction')

所以最后,我有一种方法可以创建我们可能在 Ruby on Rails 中看到的典型 CRUD 场景,但我不认为这是实现它的理想方式。然而,我确实相信,此时,ember-data 团队也不相信。

对于那些有兴趣将 CRUD 功能用作 Ember 的控制器和路由混合的人,我有一个Gist,其中包含我目前使用的代码。这工作正常,可以从保存错误和验证错误中恢复。希望随着 ember-data 的发展,我可以继续完善这一点。

于 2013-02-12T21:34:29.043 回答
8

在 1.0.0-beta5 中添加 DS.Errors (请参阅https://github.com/emberjs/data/commit/994f3b234ef899b79138ddece60d8b214c5449e3)您应该能够调用...

record.get("errors").clear();

这将清除以前的错误和触发器becameValid

于 2014-01-17T18:56:07.833 回答
2

您可以在其上触发becameValid事件:

record.send("becameValid");

这应该将模型转换为未提交状态。

于 2013-02-10T13:29:44.603 回答
0

您可以尝试将模型的并行表示创建为未持久化但具有与持久化模型相同的属性的 Ember.Object。如果您的 ajax 在错误状态下反弹,您可以使用 ajax 方法提供的错误回调来执行某些操作。

在这种情况下,“某事”可能是删除记录,然后将虚拟对象中的属性克隆到新记录中并重新保存记录。在成功回调中,只需销毁您的临时对象,如果所有记录都是干净的,则清除您的临时对象(以防止延迟临时对象)。

这也可能是疯狂的......但它作为一种选择让我感到震惊。

于 2013-02-08T10:10:12.383 回答