创建后的Ember数据编辑“错误:在状态root.loaded.updated.uncommitted

时间:2016-07-04 02:22:06

标签: ember.js ember-data race-condition emberfire

tl; dr:在模型保存正式不受支持的情况下编辑模型的属性?我似乎记得,在大约2013年,国家机器拒绝了在记录处于飞行状态时进行编辑的尝试,但我认为该限制已被删除。它不再抛出状态机错误......它似乎后来导致错误:/

在我正在处理的应用程序中,按Enter键会创建一个新条目并聚焦标题字段,让用户立即开始输入。对该字段的更改将通过去抖动保存自动保留。一般情况下这很好用,但如果我开始输入太快,我会收到以下错误:

Attempted to handle event `didCommit` on <app@model: ...> while in state root.loaded.updated.uncommitted.

(我在底部包含了完整的错误和回溯[1])

该记录看起来似乎已经通过Firebase适配器正确保存到服务器(EmberFire),但从那时起该应用程序还有其他奇怪之处(可能是因为运行的迭代)循环在完成之前爆炸。)

要了解情况,我已将观察者附加到模型的currentState.stateNametitle字段中。对于无错误的创建和保存,记录将通过以下状态:

      [Press Enter; Pause]
               |
               V
 root.loaded.created.uncommitted
               |
               V
<title observer fires with blank>
               |
               V
   root.loaded.created.inFlight
               |
               V
       root.loaded.saved
               |
               V
        [Type in title]
               |
               V
root.loaded.updated.uncommitted
               |
               V
<title observer fires with value>
               |
               V
  root.loaded.updated.inFlight
               |
               V
       root.loaded.saved

出现错误时,过程如下所示:

 [Press Enter & type immediately]
               |
               V
 root.loaded.created.uncommitted
               |
               V
<title observer fires with blank>
               |
               V
   root.loaded.created.inFlight
               |
               V
[title observer fires with value]
               |
               V
       root.loaded.saved
               |
               V
root.loaded.updated.uncommitted
               |
               V
        <Error appears>
               |
               V
  root.loaded.updated.inFlight
               |
               V
       root.loaded.saved

我最初的想法是错误是由初始创建完成之前的第二次保存引起的,但错误发生在root.loaded.updated.uncommitted - 之前记录进入{{ 1}}。我很确定这意味着问题是由字段的实际编辑引起的,而不是对记录root.loaded.updated.inFlight的调用。

编辑:的确,完全取消保存标题似乎没有任何效果。这似乎表明问题确实源于编辑该领域。

查看回溯(下面),导致save()事件的原因并不明显。我想知道我的问题是EmberFire在模型处于错误状态时调用didCommit的错误,但是searching the EmberFire codebase doesn't turn up any calls to didSaveRecord() whatsoever因此看起来不是问题。

这只是Ember Data的设计行为吗?如果是这样的话,这似乎是一个非常严重的限制,我在任何地方都没有提到过。[2]

At one point, ED used to prevent setting properties while a record was inflight,但我认为这个限制已被删除(并没有明确阻止我这样做)。

首先想到的解决方法是缓冲对字段的写入,直到模型处于“可写”状态......除了我从未见过任何官方Ember示例那样做。

这是正确的(或至少是合理的)解决方案吗?

如果是这样,什么构成“可写”状态? didSaveRecord()以外的任何其他内容? (我可以用inFlight标志检查,对吗?)

如果没有,是否有其他官方推荐的模式来处理这个问题?

修改

在阅读an old thread about autosave时,我遇到an article that mentions a Buffered Proxy pattern(最后一个主要部分:“给我们的属性一个缓冲区”)听起来与我所描述的非常相似。这与sample code by Luke Melia from 2013Stefan Penner said they used "regularly" (at that time).有关联the ember-buffered-proxy Ember CLI addon这两者都是Ember社区的积极贡献者,所以我认为这是有效的“官方”建议,但问题仍然存在:这仍然是建议的做法三年后?

修改

该代理模式现在打包为A case of issuing a second save request while the first is still in progress.,但它的README仍然没有真正提到何时可能需要这种模式(这似乎暗示它在需要该功能的特定场景中偶尔有用,而不是修复了Ember Data的核心限制)

[1] 完整错误/追溯:

isSaving

[2] 我遇到的唯一 2 3 四个类似问题的提及是:

  1. A case of mutating data within a DS.Transform's serialize() method在这种情况下,通过去除保存来解决问题,但我已经这样做,并且如果模型保存已在进行中,则重新排队保存(通过明确检查ember.debug.js:31352 Error: Attempted to handle event `didCommit` on <app@model:task::ember965:-KLmwiGUhqrUW_CiRGb4> while in state root.loaded.updated.uncommitted. at new Error (native) at Error.EmberError (http://app.localtest.me:4200/assets/vendor.js:25781:21) at InternalModel._unhandledEvent (http://app.localtest.me:4200/assets/vendor.js:82039:13) at InternalModel.send (http://app.localtest.me:4200/assets/vendor.js:81917:14) at InternalModel.adapterDidCommit (http://app.localtest.me:4200/assets/vendor.js:82220:12) at didSaveRecord (http://app.localtest.me:4200/assets/vendor.js:89092:21) at http://app.localtest.me:4200/assets/vendor.js:89814:15 at Object.Backburner.run (http://app.localtest.me:4200/assets/vendor.js:10788:25) at _adapterRun (http://app.localtest.me:4200/assets/vendor.js:89648:31) at http://app.localtest.me:4200/assets/vendor.js:89805:13 onerrorDefault @ ember.debug.js:31352 exports.default.trigger @ ember.debug.js:52095 (anonymous function) @ ember.debug.js:53346 Queue.invoke @ ember.debug.js:333 Queue.flush @ ember.debug.js:397 DeferredActionQueues.flush @ ember.debug.js:205 Backburner.end @ ember.debug.js:560 (anonymous function) @ ember.debug.js:1126 财产)。并且,正如我之前所说,即使完全取消后标题更改自动保存似乎也没有效果。
  2. An older case that looks like it could be the same problem, but is in a Route's model() hook, where it is simple to wait for the save to complete before continuing.
  3. Another older example of setting properties while inFlight causing an invalid state transition.
  4. Ember Persistence Foundation首先,这不会再导致同样的错误。其次,提供的唯一解决方案是切换到abandoned in mid 2014,这似乎是confirmed(编辑:{{3}})

0 个答案:

没有答案