2017-08-30 122 views
3

我有一個pre標籤,帶有動態文本(頁面加載時未知)。這個文本可能有ng命令。它會看起來像這樣:AngularJS:編譯特定模板

<pre> 
    Hello <span ng-click="test('args')">world</span> angular-JS! 
</pre> 

由於這些動態代碼是不是在加載的頁面存在,angularjs不運行它們和功能test('args')將永遠不會運行。

所以,我添加了一個名爲指令compile-template

function compileTemplate($compile, $parse) 
{ 
    return { 
     link: function (scope, element, attr) 
     { 
      var parsed = $parse(attr.ngBindHtml); 
      function getStringValue() { return (parsed(scope) || '').toString(); } 

      //Recompile if the template changes 
      scope.$watch(getStringValue, function() 
      { 
       $compile(element, null, -9999)(scope); //The -9999 makes it skip directives so that we do not recompile ourselves 
      }); 
     } 
    } 
} 

現在我pre標籤是這樣的:

<pre compile-template> 
    Hello <span ng-click="test('args')">world</span> angular-JS! 
</pre> 

這是工作好。

的問題時,我的文字像我的文字開始變化:

<pre compile-template> 
    Hello <span ng-click="test('args')">world</span> angular-JS! }} 
</pre> 

當我試圖編譯該文(「世界,你好角JS}}!」)我得到這個錯誤:

Error: [$parse:lexerr] http://errors.angularjs.org/1.5.8/$parse/lexerr?p0=Unexpected%20next%20character%20&p1=s%200-0%20%5B%23%5D&p2=%23coordinates%3A21%7C37%7CN%7C87%7C04%7CW%7C%7C%7C%0A%0A%0A%7C%0A%7Cname%3D 
    at angular.js:38 
    at jc.throwError (angular.js:14179) 
    at jc.lex (angular.js:14101) 
    at s.ast (angular.js:14303) 
    at td.compile (angular.js:14771) 
    at kc.parse (angular.js:15700) 
    at g (angular.js:15865) 
    at k (angular.js:12364) 
    at ca (angular.js:9724) 
    at $b (angular.js:8743) 

這是因爲與}}破壞的JS代碼相關聯的「}}」字符串。

例子:https://jsfiddle.net/m69q87eg/

所以,basicly我特林做是爲了讓<span> s的JS,但沒有別的。

我雖然移動compile-template指令是我跨度的一部分。就像這樣:

<pre> 
    Hello <span compile-template ng-click="test('args')">world</span> angular-JS! 
</pre> 

但它不工作,因爲pre outter HTML就像文字處理。

怎麼辦?

+1

嗯,你如何填充'pre'標籤的內容?因爲我嘗試過使用['ngBindHtml'](https://docs.angularjs.org/api/ng/directive/ngBindHtml),並且所有工作都按預期進行,沒有任何錯誤。請參閱[fiddle here](https://jsfiddle.net/ymppayhb/3/)。您能否提供[最小,完整和可驗證示例](https://stackoverflow.com/help/mcve)? –

+0

當然,這是我的問題:https://jsfiddle.net/m69q87eg/ – No1Lives4Ever

+0

所以這種情況發生,因爲它試圖解析'{{...}}之間的表達式,當然這是不正確的。所以有一個問題 - 你可以修改你的模板嗎?你可以嘗試用['ngNonBindable'指令](https://docs.angularjs.org/api/ng/directive/ngNonBindable)來包裝這部分,如'(21°37'N 87 ...}})'。如果沒有,那麼我們需要考慮如何修改您的指令。 –

回答

1

您可以嘗試使用自定義的,這將$compile只在屬性被設置的標籤(使用querySelectorAll() method或您選擇的其他一些篩選邏輯)ngBindHtmlCompile指令:

var module = angular.module("demo", []); 
 

 
module.directive('ngBindHtmlCompile', ['$compile', '$parse', function ($compile, $parse) { 
 
    return { 
 
    link: function (scope, element, attr) { 
 
     var parsed = $parse(attr.ngBindHtmlCompile); 
 
     function getStringValue() { return (parsed(scope) || '').toString(); } 
 
     scope.$watch(getStringValue, function (val) { 
 
     element.html(val); 
 
     if (!!attr.compileTags) { 
 
      $compile(element[0].querySelectorAll(attr.compileTags))(scope); 
 
     } else { 
 
      $compile(element, null, -9999)(scope); 
 
     }   
 
     }); 
 
    } 
 
    } 
 
}]); 
 

 
module.controller('Demo', ['$scope', '$window', function Demo($scope, $window) { 
 
    var vm = this; 
 
    
 
    vm.template1 = ` 
 
populations of Eurasia <span>{{vm.untilStr}}</span> 1492, when Christopher Columbus first <span class=\"highlight-1\" ng-click=\"vm.test(2810)\">sailed into Caribbean waters on a quest to find a sea route to Asia. At that time the Western Hemisphere in general was unknown to Europeans. Following the discovery of the islands by Columbus, the area was quickly colonised by several Western cultures (initially Spain, then later</span> 
 

 
In the Yucatan Channel. The same limit as that described for the Gulf of Mexico [A line joining Cape Catoche Light (21°37′N 87°04′W/21.617°N 87.067°W/21.617; -87.067{{#coordinates:21|37|N|87|04|W||| 
 

 

 
| 
 
|name= 
 
}}) -- 1213123 <span class=\"highlight-1\" ng-click=\"vm.test(4117)\">and the extreme of Agujereada </span>`; 
 
     
 
    vm.test = function(args){ $window.alert(args); }; 
 
    vm.untilStr = "until"; 
 
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> 
 

 
<div ng-app="demo" ng-controller="Demo as vm"> 
 
    <pre ng-bind-html-compile="vm.template1" compile-tags="span"></pre>   
 
    <br/> 
 
</div>