模板中的指令内的指令不起作用

时间:2015-01-07 23:06:45

标签: javascript html angularjs angularjs-directive

我是一个Angular noob。我将窗格结构化为表集并使用指令将模板HTML摘要保留在表实现中。窗格正在被正确转换,但内部仅包含文本而不是表格结构。这是我的代码:

<!DOCTYPE html>
<html>

<head>
<script src= "angular.js"></script>
<script src= "angular-sanitize.js"></script>
</head>

<body ng-app="pp">

<div ng-controller="ppMain">
  <ul class="menu">
    <li ng-repeat="pageID in homePageList">{{pages[pageID].str}}</li>
  </ul>
  <div>
    <div ng-repeat="pageID in pageList" ng-bind-html="pages[pageID].template">
    </div>
  </div>
</div>

<script>

var pp = {
    ctl: {}
};

pp.mod = angular.module('pp', ['ngSanitize']);
pp.mod.directive({
    'ppHeader': function () {
        return ({
        });
    },
    'ppGroup': function () {
        return ({
            template: '<table ng-transclude></table>',
            transclude: true,
            restrict: 'EA'
        });
    },
    'ppRow': function () {
        return ({
            template: '<tr ng-transclude></tr>',
            transclude: true,
            restrict: 'EA'
        });
    },
    'ppLabel': function () {
        return ({
            template: '<td ng-transclude></td>',
            transclude: true,
            restrict: 'EA'
        });
    },
    'ppValue': function () {
        return ({
            template: '<td ng-transclude></td>',
            transclude: true,
            restrict: 'EA'
        });
    },
});
pp.ctl.main = pp.mod.controller('ppMain', ['$scope', function ($scope) {
    $scope.curPage = 'page1';
    $scope.pages = {
        "page1": {
            str: "page 1",
            template:'\
                <pp-group>\
                    <pp-row>\
                        <pp-label>Page:</pp-label><pp-value>1</pp-value>\
                    </pp-row>\
                </pp-group>\
            '},
        "page2": {
            str: "page 2",
            template:'\
                <pp-group>\
                    <pp-row>\
                        <pp-label>Page:</pp-label><pp-value>2</pp-value>\
                    </pp-row>\
                </pp-group>\
            '},
        "page3": {
            str: "page 3",
            template:'\
                <pp-group>\
                    <pp-row>\
                        <pp-label>Page:</pp-label><pp-value>3</pp-value>\
                    </pp-row>\
                </pp-group>\
            '}
    };
    $scope.pageList = ["page1","page2","page3"];
    $scope.homePageList = ["page2", "page3"];

}]);


</script> 

</body>
</html>

使用调试器查看生成的DOM,我找不到表,只找到文本。

1 个答案:

答案 0 :(得分:0)

ng-bind-html无法实现这一点,因为ng-sanitize不会编译html。它只能用于静态内容。您需要自己创建一个指令。

这样的事情:

.directive('compileHtml', function($compile) {
  return {
    restrict: 'A',
    link: function(scope, elm, attrs) {
      var template = scope.$eval(attrs.compileHtml); //get the template by evaluating
      elm.html(template); //set the html
      $compile(elm.contents())(scope); //compile the contents
    }
  }
});

另外请记住,您有没有替换的子指令,这意味着您将创建无效的html,由table创建的ppGroupppRow作为子级导致无效的html和它会将指令内容从表中推出,编译将无法正常进行。因此,您需要在这些指令上使用选项replace:true

然而,动态编译html是非常不安全的,除非你知道它是来自可靠来源,这是$sce使用的ng-bind-html服务。它清理boundhtml。

<强>演示

&#13;
&#13;
var pp = {
  ctl: {}
};

pp.mod = angular.module('pp', ['ngSanitize']);

pp.mod.directive({
  'ppHeader': function() {
    return ({});
  },
  'ppGroup': function() {
    return ({
      template: '<table ng-transclude></table>',
      transclude: true,
      restrict: 'EA'
    });
  },
  'ppRow': function() {
    return ({
      replace: true,
      template: '<tr ng-transclude></tr>',
      transclude: true,
      restrict: 'EA'
    });
  },
  'ppLabel': function() {
    return ({
      replace: true,
      template: '<td ng-transclude></td>',
      transclude: true,
      restrict: 'EA'
    });
  },
  'ppValue': function() {
    return ({
      replace: true,
      template: '<td ng-transclude></td>',
      transclude: true,
      restrict: 'EA'
    });
  },
}).directive('compileHtml', function($compile) {
  return {
    restrict: 'A',
    link: function(scope, elm, attrs) {
      var template = scope.$eval(attrs.compileHtml);
      elm.html(template);
      $compile(elm.contents())(scope);
    }
  }
});
pp.ctl.main = pp.mod.controller('ppMain', ['$scope',
  function($scope) {
    $scope.curPage = 'page1';
    $scope.pages = {
      "page1": {
        str: "page 1",
        template: '\
                <pp-group>\
                    <pp-row>\
                        <pp-label>Page:</pp-label><pp-value>1</pp-value>\
                    </pp-row>\
                </pp-group>\
            '
      },
      "page2": {
        str: "page 2",
        template: '\
                <pp-group>\
                    <pp-row>\
                        <pp-label>Page:</pp-label><pp-value>2</pp-value>\
                    </pp-row>\
                </pp-group>\
            '
      },
      "page3": {
        str: "page 3",
        template: '\
                <pp-group>\
                    <pp-row>\
                        <pp-label>Page:</pp-label><pp-value>3</pp-value>\
                    </pp-row>\
                </pp-group>\
            '
      }
    };
    $scope.pageList = ["page1", "page2", "page3"];
    $scope.homePageList = ["page2", "page3"];

  }
]);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular-sanitize.min.js"></script>
<div ng-app="pp">

  <div ng-controller="ppMain">
    <ul class="menu">
      <li ng-repeat="pageID in homePageList">{{pages[pageID].str}}</li>
    </ul>
    <div>
      <div ng-repeat="pageID in pageList" compile-html="pages[pageID].template">
      </div>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;