2013-03-21 168 views
1

如果我想在一個視圖渲染完成後調用一個jquery插件(例如在dom中插入一個表),除了使用window.setTimeout()做這件事之外,是否還有其他可能性?ember.js路由渲染:用setTimeout()操作dom?

此代碼的工作(1毫秒超時;那怪異):

Route.HomeRoute = Ember.Route.extend({ 
     renderTemplate: function() { 

      this.render("home"); // render the home view 

      window.setTimeout(function() { 
       $(".tables").insertTables(); // this would add a table 
      }, 1); 

     } 
    }) 

但這碼不起作用:

Route.HomeRoute = Ember.Route.extend({ 
     renderTemplate: function() { 

      this.render("home"); // render the home view 

      $(".tables").insertTables(); // this would add a table 

     } 
    }); 

我知道,有Ember.View.didInsertElement() ,但是因此我必須在父View上設置一個回調函數,並且只是想知道爲什麼上面的代碼示例沒有按預期工作。

非常感謝!

回答

2

我不知道羯羊我的答案是100%準確,但我想這是怎麼可以這樣解釋:

我猜問題是,你認爲渲染()方法其工作同步。但這種情況並非如此。相反,它調度HomeView的渲染。渲染被安排在Ember的RunLoop中。在第二個示例中,您的代碼調度渲染,然後立即嘗試訪問其DOM元素(我猜.tables是家庭模板的一部分)。但視圖不是在這個時候渲染的!第一個例子有效,因爲有1ms超時。 在此超時期間,Ember RunLoop將啓動並啓動其魔法。它執行渲染,之後CPU再次空閒時,可以調用超時函數。

其實你要在這裏做的是:do something on my DOM, when the View was successfully rendered。這可以在Ember中完成,而不使用setTimeout。以下代碼訪問RunLoop並計劃在RunLoop結束時執行的函數。

Ember.run.next(function() { 
    $(".tables").insertTables(); // this would add a table 
}); 

這裏是關於RunLoop的文章,如果你想了解灰燼的那些細節是很重要的理解,: - Article by machty

最後但並非最不重要的:它接縫完全尷尬在Route中執行這樣的DOM操作。你的路線應該永遠是免費的。元素和選擇器和jQuery插件只能用於視圖層。其他一切似乎都不好。也許你想分享關於你爲什麼選擇這種方法的更多細節?這可能是一個更好的解決方案。

+0

我認爲這是我們第二次在同一時間回答:) – 2013-03-21 09:31:21

+0

總是很高興看到另一個人試圖解釋同樣的問題:-) – mavilein 2013-03-21 10:25:36

0

第二個示例不起作用的原因可能是由於Ember.js Run Loopthis.render安排稍後在當前運行循環中插入dom。

DOM插入在運行循環結束時完成,並且通過使用setTimeout,您在運行循環結束後調用插件,因此保證模板已注入到DOM中。 (不需要1ms,0ms可能會工作)

你可能會說這個運行循環的東西非常複雜,特別是對於Ember.js初學者來說。事情是,理想情況下,它應該是應用程序開發人員透明。之所以遇到它的副作用,是因爲DOM操作不應該在路由器中處理

我的第一反應是告訴你使用didInsertElement或者View裏面的任何代碼或鉤子,因爲那是DOM操作應該發生的地方。但似乎你知道這一點,不能出於某種原因使用它(我無法證實或否認,因爲我沒有足夠的信息)。

我給你的建議,儘量做到這一點didInsertElement

+0

謝謝,夥計們!運行循環正是我不明白的東西。這就是爲什麼我「接受」mavilein的答案作爲正確的答案,謝謝你對該文章的鏈接!我有一些瘋狂的架構和清理 - 現在我可以在我覆蓋的didInsertElement函數中執行此操作。但是,是的,我的問題是對運行循環的理解。 – 2013-03-22 08:19:52