2014-12-03 202 views
0

我使用$ compile服務遇到了一個非常奇怪的情況。我試圖編譯一個我從後臺使用我的控制器獲得的模板。Angular的編譯不起作用

這裏是JS:

angular.module('app', []); 

angular.module('app').controller('AC', ['HtmlProcessor', function Actrl(HtmlProcessor) { 
    this.abc = 'Hello!'; 
    this.do = function() { 
    alert(HtmlProcessor.getHTML(this)); 
    }; 
}]); 

angular.module('app').service('HtmlProcessor', ['$compile', function ($compile) { 
    this.getHTML = function (scope) { 
    return $compile('<p>{{ abc }}</p>')(scope).html(); 
    }; 
}]); 

這裏是HTML:

<!DOCTYPE html> 
<html ng-app="app"> 
<head> 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script> 
    <meta charset="utf-8"> 
    <title>JS Bin</title> 
</head> 
<body ng-controller="AC as ac"> 
    <button ng-click="ac.do()">Compile!</button> 
</body> 
</html> 

所以,問題是,當我打電話ac.do()我得到一個錯誤(在角的textInterpolateFn)和模板未編譯。我究竟做錯了什麼?

回答

2

在這個函數簽名,你期待一個Scope實例:

/* 
* @param {Scope} scope 
*/ 
this.getHTML = function (scope) { 

而且,$compile返回一個複合鏈接函數,該函數需要一個作用域,該作用繼而傳遞到所有指令控制器和鏈接函數,這些函數也期望範圍類型。

你傳遞一個錯誤的類型的功能:

alert(HtmlProcessor.getHTML(this)); 

在你的情況關鍵字失去了它的上下文,但是即使你救了它,像這樣:

this.do = angular.bind(this, function() { 
    alert(HtmlProcessor.getHTML(this)); 
}); 

它止跌」 t工作,因爲控制器的上下文(這個)不是範圍類型,它只是一個泛型函數對象的類型構造

例如,在你的代碼,它會失敗在這個指令:

enter image description here

+0

是的,你是對的!我後來在解決問題的同時得到了它。 – 2014-12-03 11:53:23

6

最後,我發現問題的根源。鏈接後我必須運行digest循環。因此,我創建一個新的範圍,用數據填充它,把它傳遞給鏈接功能,引發消化:

this.getHTML = function (scope) { 

    var newScope = $rootScope.$new(); 
    angular.extend(newScope, scope); 

    var compiled = $compile('<p>{{ abc }}</p>')(newScope); 

    newScope.$apply(); 

    return compiled.html(); 
}; 
+0

這是非常有益的!消化循環的需求似乎是Angular中的一個bug,它看到事情是如何不一致的:當從某些範圍繼承(而不是'$ rootScope',我會使用一些'$ scope')時,它起作用,當從別人不會;非常隨機(但可能與父範圍的當前摘要狀態有關)。調用'$ digest'可以修復一切。然而!!!你不能調用'$ apply'或$ $ digest';這意味着您必須在摘要循環之外運行整個編譯過程(如果使用'$ new'作用域)(例如使用'$ timeout'或'setTimeout')。 – Domi 2015-04-20 12:39:22