2014-12-03 75 views
1

我有一個服務,我打電話$compile編譯我的模板。 JS中的函數一個接一個地執行。但是,爲了得到我的最終HTML,我必須把html()放在超時回調中。否則,我只能得到我的模板{{ placeholders }}。問題是爲什麼我需要在這裏使用超時?這裏是我的代碼:是angular的編譯函數異步?

var newScope = $rootScope.$new(true); 
angular.extend(newScope, data); 
var compiled = $compile(template); 
var linked = compiled(newScope); 

$timeout(function() { 
    def.resolve(linked.html()); 
}); 
+1

這是包裹在一個綁定的HTML事件?像「點擊」?你可能需要'$ scope。$ apply()'。 '$ timeout'做一個'$ apply'作爲下面的副作用,所以這可能是它工作的原因。 – 2014-12-03 18:06:27

+1

此方法在角度事件上稱爲$。但我的問題是爲什麼我需要在$ timeout中包裝linked.HTML()'或者調用$ apply?其實,這不是因爲$申請。我也可以用0延遲設置vanilla'setTimeout',並用編譯好的模板解析promise。它似乎與JS內部函數調用隊列有關。我認爲在js函數中一個接一個地執行。無論需要多少時間來執行一個函數。但是這個案例表明它不是。 – 2014-12-03 19:46:24

回答

1

不,$ compile不是異步的。調用$ timeout是必要的,因爲瀏覽器的性質以及JavaScript和DOM之間的關係。 $超時允許更新DOM,以便您對.html()的調用實際上有將返回 html。

你的例子正確使用$ compile和$ timeout。

有兩點要注意:

$超時已經返回其與傳遞函數的返回值解決的承諾,所以你可以簡單地這樣做:

return $timeout(function(){ 
    return linked.html(); 
}); 

當你有它,你的模板的最外層(根)元素會被拋棄,因爲.html()返回該元素的innerHTML。如果您需要保留該根元素,你可以在一個div首套它像這樣:

return $timeout(function(){ 
    return angular.element('<div/>').append(linked).html(); 
}); 

完整的示例:

var $scope = angular.extend($rootScope.$new(true), data); 
var template = angular.element($templateCache.get(templateName)); 

$compile(template)($scope); 

return $timeout(function(){ 
    return angular.element('<div/>').append(template).html(); 
});