tl; dr:在模型保存正式不受支持的情况下编辑模型的属性?我似乎记得,在大约2013年,国家机器拒绝了在记录处于飞行状态时进行编辑的尝试,但我认为该限制已被删除。它不再抛出状态机错误......它似乎后来导致错误:/
在我正在处理的应用程序中,按Enter键会创建一个新条目并聚焦标题字段,让用户立即开始输入。对该字段的更改将通过去抖动保存自动保留。一般情况下这很好用,但如果我开始输入太快,我会收到以下错误:
Attempted to handle event `didCommit` on <app@model: ...> while in state root.loaded.updated.uncommitted.
(我在底部包含了完整的错误和回溯[1])
该记录看起来似乎已经通过Firebase适配器正确保存到服务器(EmberFire),但从那时起该应用程序还有其他奇怪之处(可能是因为运行的迭代)循环在完成之前爆炸。)
要了解情况,我已将观察者附加到模型的currentState.stateName
和title
字段中。对于无错误的创建和保存,记录将通过以下状态:
[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 2013的Stefan 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 四个类似问题的提及是:
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
财产)。并且,正如我之前所说,即使完全取消后标题更改自动保存似乎也没有效果。Route
's model()
hook, where it is simple to wait for the save to complete before continuing. inFlight
causing an invalid state transition.