简体   繁体   English

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

[英]Directive within a directive within a template not working

I'm an Angular noob. 我是Angular菜鸟。 I'm structuring my panes as sets of tables and using directives to keep the template HTML abstract from the table implementation. 我将窗格构造为表集,并使用指令将模板HTML与表实现抽象化。 The panes are getting transcluded correctly, but interior only contains the text not the table structure. 窗格已被正确排除,但是内部仅包含文本,而不包含表结构。 Here's my code: 这是我的代码:

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

Looking at the generated DOM with the debugger, I find no tables, only text. 用调试器查看生成的DOM,我发现没有表,只有文本。

That is not possible with ng-bind-html because ng-sanitize does not compile the html. 对于ng-bind-html来说这是不可能的,因为ng-sanitize不会编译html。 It can only be used for static content. 它只能用于静态内容。 You would need to create a directive yourself for this. 您需要为此自己创建一个指令。

Something like this: 像这样:

.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
    }
  }
});

Also remember that you have child directives with no replace, which means you will be creating invalid html, table created by ppGroup will have ppRow as child which results in invalid html and it will push the directive content out of the table and compilation will not happen properly. 还记得你有没有更换孩子的指令,这意味着你将创建无效的HTML, table通过创建ppGroup将有ppRow为孩子导致无效的HTML,这将推动该指令的内容出表,并汇编不会发生正确地。 So you would instead need to use the option replace:true on these directives. 因此,您将需要在这些指令上使用选项replace:true

However it will be really unsafe to compile the html dynamically though unless you know it is from a trusted source which is what $sce service used by ng-bind-html does. 但是,动态编译html确实是不安全的,除非您知道它来自受信任的源,这就是ng-bind-html使用的$sce服务所做的。 It sanitizes the boundhtml. 它清除boundhtml。

Demo 演示版

 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"]; } ]); 
 <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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM