javascript – AngularJS:编译特定模板

我有一个带有动态文本的预标记(在加载页面时未知).此文本可能有ng命令.它看起来像这样:

<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>

当我尝试编译此文本时(“Hello world angular-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/

所以,基本上我要做的是允许使用JS< span> s,但没有别的.

我想将compile-template指令移动到我的span的一部分.像这样:

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

但它不起作用,因为pre outter HTML被视为文本.

该怎么办?

最佳答案 您可以尝试使用自定义ngBindHtmlCompile指令,它将仅使用属性中提供的标记
$compile(使用
querySelectorAll() method或您选择的其他一些过滤逻辑):

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>
点赞