AngularJS ng-click在编译尝试后没有触发

时间:2016-03-05 09:47:32

标签: javascript angularjs

我的指令有一个模板,其中包含一个名为content的范围变量:

<div class="directive-view">
    <span class="directive-header">My Directive</span>
    <span ng-bind-html="content"></span>
</div>

我有以下指令,它监视content的更改,然后编译元素的内容:

(function () {
    "use strict";

    angular
        .module('myApp.myDirective', [])
        .directive("myDirective", myDirective);

    function myDirective($compile, $sce) {
        return {
            restrict: 'E',
            scope: {
            },
            templateUrl:'../partials/directives/my-directive.html',
            controller: function($scope) {
                $scope.testAlert = function(msg) { alert(msg) };
            },
            link: function (scope, element, attrs, ctrl) {

                scope.content = $sce.trustAsHtml('Initial value');

                scope.$watch(attrs.content, function(value) {
                    element.html(value);
                    console.log("Content changed -- recompiling");
                    $compile(element.contents())(scope);
                });

                scope.content = $sce.trustAsHtml('<button ng-click="testAlert(\'clicked!\')">Click</button>');
            }
        };
    }
})();

该指令呈现button元素。但是,单击testAlert()元素时,不会调用控制器函数button

此外,在$watch设置为content后,Initial value回调仅被调用一次。将content设置为按钮后,不会触发回调。 (我原以为当attrs.content的值发生变化时会触发回调。)

如果我手动重新编译元素:

$compile(element.contents())(scope);

button元素在点击时仍然不会触发testAlert功能。

如何正确地重新编译元素内容,以便进行正确的绑定?

1 个答案:

答案 0 :(得分:1)

在这种情况下,您不需要使用$sce。仅使用$compile

jsfiddle上的实例。

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope) {
    $scope.name = 'Superhero';
		$scope.changeTEmplate = function(){
      $scope.cont = '<div><b>i\'m changed</b></div>';
    }
  })
  .directive("myDirective", function myDirective($compile) {
    return {
      restrict: 'E',
      scope: {content:"="},
      template: `<div class="directive-view">
    <span class="directive-header">My Directive</span>
    <span></span>
    </div>`,
      controller: function($scope) {
        $scope.testAlert = function(msg) {
          alert(msg)
        };
      },
      link: function(scope, element, attrs, ctrl) {
        scope.$watch('content', function(value) {
          var span = angular.element(element.find('span')[1]);
          span.html(value);
          console.log("Content changed -- recompiling",value);
            $compile(span)(scope);
        });
        scope.content = '<button ng-click="testAlert(\'clicked!\')">Click</button>';
      }
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="MyCtrl">
    Hello, {{name}}!
    <button ng-click="changeTEmplate()"> change Content</button>
    <my-directive content="cont"></my-directive>
  </div>
</div>