使用EmberJS调用jQuery插件创建竞争条件

时间:2014-08-08 21:49:32

标签: jquery dom ember.js datatables

我使用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;处理这个?谢谢!

1 个答案:

答案 0 :(得分:2)

我希望这可行:

Ember.run.next(this, function() {
    Ember.$('#orgUsers').DataTable();
});

这比您的setTimeout代码更受欢迎。 Ember将为下一个运行循环安排您的功能。从didInsertElement队列中的任务调用render。您对scheduleOnce的呼叫进入afterRender队列,即#34;下游&#34;来自render队列,但是在相同的循环迭代中。

使用run.next会将任务安排在新的运行循环中,因此在当前循环中不会出现生命周期问题。