AngularJS 字符串替换和 $compile

AngularJS string replacement and $compile

AngularJS 的新功能 - 我正在尝试创建一个函数来查找 "tokens" 特定文本,并将它们替换为绑定到控制器上函数的 ng-click 指令。例如,在我的数据库中,我有很多类似这样的文本字段:

<p>Your [labor] cost is included in price</p>

我希望这样结束:

<p>Your <a href="#" ng-click="showModal('labor')">labor</a> cost is included in price.</p>

我可以用过滤器替换 [labor] 令牌,但我对如何合并 $compile 以将 ng-click 绑定到 $scope.showModal() 有点迷茫在我的控制器上。

如有任何帮助,我们将不胜感激。谢谢。

我现有的过滤器:

myApp.filter('parseHtml', function ($sce) {

    return function (text) {

        var link = '<a href="" ng-click="getModal(\'labor\')">Labor</a>';
        var replaced = text.replace(/\[labor\]/g, link);

        return $sce.trustAsHtml(replaced);
    };
});

在html

<span ng-bind-html="package.price | parseHtml"></span>

控制器

myApp.controller('MainController',
    function MainController($scope, $http) {

        $scope.getpackage = function (slug) {

            var onpackageComplete = function (response) {
                $scope.package = response.data;
            };
            $http.get('/packages/api/' + slug + '/detail')
                .then(onpackageComplete);
        };

        $scope.getModal = function (name) {

            $scope.modalVisible = true;
            if (name === 'labor') {
                $scope.modalBody = '/path/to/html/snippet/ModalLabor.html';
            } else if (name === '') {
                $scope.modalBody = '';
            }

        };
    }
);

参考 Compiling dynamic HTML strings from database 中提供的公认答案,这应该可以解决问题

更改指令过滤器,它使用令牌获取内容,将其替换为点击功能并编译内容,放入DOM再次。请仔细查看下面的演示,以了解如何操作。

angular
  .module('app', [])

  //The new directive! (which replaced the old filter)
  .directive('parseHtml', function($compile) {
    return {
      restrict: 'A',
      replace: true,
      link: function(scope, iElem, attrs) {
        var link = '<a href="" ng-click="getModal(\'labor\')">Labor</a>';

        scope.$watch(attrs.parseHtml, function(text) {
          if (text) {
            var replaced = text.toString().replace(/\[labor\]/g, link);
            iElem.html(replaced);
            $compile(iElem.contents())(scope);
          }
        })
      }
    }
  })

  //sample controller
  .controller('MainController',
    function MainController($scope, $http) {
      var p = 1;
      
      $scope.getpackage = function() {debugger;
        $scope.package = {
          price: "Value is " + p + " hundred - [labor]"
        };
        p = p + 1;
      };

      $scope.getModal = function(name) {
        console.log('getModal clicked!');
        alert('getModal clicked!');
      };
    }
  );
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="MainController">

  <!--mock request-->
  <button ng-click="getpackage()"> Get Package</button> <br /> <br />

  <!-- how to use the directive -->
  <span parse-html="package.price"></span>

</div>

重要提示:link 中的操作是getModal(固定在指令中)。如果你也需要动态添加它,你也需要将该函数作为参数传递给指令。新的实施需要一些改变。