我使用jQuery DataTables plugin在Ember中渲染数据。我遇到了经典的竞争条件问题,我对Ember和Ember运行循环的一些理解必须是不完整的。这是发生了什么。
<table>...<tbody>{{#each user in model}}...
didInsertElement
方法调用DataTables库,并将其包装在Ember.run.scheduleOnce('afterRender', function() { $('#myTable').DataTable(); })
Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM.
我看过类似的StackOverflow帖子:
但是这些修复似乎不起作用。我怀疑DataTables试图在 Ember完成呈现之前更新DOM ,但是为什么我的被叫Ember.run.scheduleOnce('afterRender', ...)
地址不是?
奇怪的是,我可以通过以下方式让它发挥作用:
视图中的旧(种族条件)代码:
didInsertElement: function() {
Ember.run.scheduleOnce('afterRender', function() {
$('#orgUsers').DataTable();
});
}
视图中的新工作代码:
didInsertElement: function() {
setTimeout(function() {
$('#orgUsers').DataTable();
}, 0);
}
请注意,我已指定javascript setTimeout
延迟0秒!但每次都有效。
有人可以帮助我理解(1)为什么将这个包装在setTimeout()
中解决我所有的问题,(2)什么是&#34; Ember Way&#34;处理这个?谢谢!
答案 0 :(得分:2)
我希望这可行:
Ember.run.next(this, function() {
Ember.$('#orgUsers').DataTable();
});
这比您的setTimeout
代码更受欢迎。 Ember将为下一个运行循环安排您的功能。从didInsertElement
队列中的任务调用render
。您对scheduleOnce
的呼叫进入afterRender
队列,即#34;下游&#34;来自render
队列,但是在相同的循环迭代中。
使用run.next
会将任务安排在新的运行循环中,因此在当前循环中不会出现生命周期问题。