Gab*_*ant 6 race-condition ember.js ember-data emberfire
tl; dr:在模型保存正式不支持的情况下编辑模型的属性?我似乎记得,在大约2013年,国家机器拒绝了在记录处于飞行状态时进行编辑的尝试,但我认为该限制已被删除.它不再抛出状态机错误......它似乎只会导致错误:/
在我正在处理的应用程序中,按Enter键创建一个新条目并聚焦标题字段,让用户立即开始输入.对该字段的更改将通过去抖动保存自动保留.通常这很好用,但如果我开始输入太快,我会收到以下错误:
Attempted to handle event `didCommit` on <app@model: ...> while in state root.loaded.updated.uncommitted.
Run Code Online (Sandbox Code Playgroud)
(我在底部包含了完整的错误和追溯[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
Run Code Online (Sandbox Code Playgroud)
出现错误时,过程如下所示:
[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
Run Code Online (Sandbox Code Playgroud)
我最初的想法是错误是由初始创建完成之前的第二次保存引起的,但错误发生在root.loaded.updated.uncommitted- 记录进入之前root.loaded.updated.inFlight.我很确定这意味着问题是由字段的实际编辑引起的,而不是save()对记录的调用.
编辑:确实,完全删除标题的保存似乎没有任何影响.这似乎表明问题确实源于编辑领域.
看一下追溯(下面),导致didCommit事件的原因并不明显.我在想,如果我的问题是余烬的调用故障didSaveRecord()而模型是在错误状态,但搜索代码库余烬任何电话不转达到didSaveRecord()任何这样就不会似乎是问题.
这只是Ember Data的设计行为吗?如果是这样,它似乎是一个非常严重的限制,我没有在任何地方提到过.[2]
在某一点上,ED用于防止在记录处于飞行状态时设置属性,但我认为该限制已被删除(并且它并未明确阻止我像以前那样这样做).
我想到的第一个解决方法是缓冲对字段的写入,直到模型处于"可写"状态......除了我从未见过任何官方Ember示例那样做.
这是正确的(或至少是合理的)解决方案吗?
如果是这样,什么构成"可写"状态?还有什么inFlight?(我可以用isSaving旗子检查一下,对吧?)
如果没有,是否有其他官方推荐的模式来处理这个问题?
编辑:
在阅读有关自动保存的旧帖子时,我遇到了一篇文章,其中提到了一个缓冲代理模式(最后一个主要部分:"给我们的属性一个缓冲区")听起来与我所描述的非常类似.这与Luke Melia从2013年开始的示例代码相关联,Stefan Penner称他们"经常"使用(当时).这两者都是Ember社区的积极贡献者,所以我会把它作为有效的"官方"建议,但问题仍然存在:三年后这仍然是建议的方法吗?
编辑:
该代理模式现在打包为ember-buffered-proxy Ember CLI插件,但它的README仍然没有真正提到何时可能需要这种模式(这似乎暗示它在需要该功能的特定场景中偶尔有用,而不是修复了Ember Data的核心限制)
[1]完整错误/追溯:
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
Run Code Online (Sandbox Code Playgroud)
[2]只有2 3 4提到的,我碰到过类似的问题:
isSaving属性),则重新排队保存.并且,正如我之前所说,甚至完全摆脱后标题更改自动保存似乎没有效果.DS.Transform的serialize()方法Route的model()挂钩,它是简单的等待保存完成后再继续.inFlight导致无效状态转换时设置属性的较旧示例.首先,这不会再导致相同的错误.其次,提供的唯一解决方案是切换到Ember Persistence Foundation,该基金会似乎在2014年中期被废弃(编辑:已确认)