在另一个指令内(在转发器模板中)呈现指令

时间:2013-05-10 09:30:52

标签: angularjs

我正在尝试在另一个指令中呈现一个指令(不确定模板中的转发器是否正在工作),它似乎只是输出为文本而不是编译指令(此处的plunker代码:http://plnkr.co/edit/IRsNK9

关于如何让它在转发器内正确呈现my-dir-one,my-dir-two,my-dir-three指令的任何想法?

的index.html

<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.js"></script>
  <script src="app.js"></script>
  <script id="partials/addressform.html" type="text/ng-template">
      partial of type {{type}}<br>
  </script>
</head>
<body>
  <div container></div>

  <br /><br /><br />
  <b>Below is just to test the directives are actually usable outside the repeater</b>
  <div my-dir-one></div>
  <div my-dir-two></div>
  <div my-dir-three></div>
</body>
</html>

app.js

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

app.directive('container', function () {

  return {
        restrict: 'A',
        scope: {},
        replace: true,

        template: '<div class="views">' +
                  '    <div class="view" ng-repeat="view in views">' +
                  '        <div {{view.dir}}>{{view.dir}}</div>' +
                  '    </div>' +
                  '</div>',

        link: function (scope, elm) {

            scope.views = [
        { dir: 'my-dir-one' },
        { dir: 'my-dir-two' },
        { dir: 'my-dir-three' }
      ];
        }
    }
});

app.directive('myDirOne', function () {
  return {
    restrict: 'A',
    scope: {},
    replace: true,
    template: '<div>This is directive one.</div>'
  }
});

app.directive('myDirTwo', function () {
  return {
    restrict: 'A',
    scope: {},
    replace: true,
    template: '<div>This is directive two.</div>'
  }
});

app.directive('myDirThree', function () {
  return {
    restrict: 'A',
    scope: {},
    replace: true,
    template: '<div>This is directive three.</div>'
  }
});

2 个答案:

答案 0 :(得分:8)

我设法通过重写代码来解决这个问题:

首先,我更新了模板代码,如下所示:

template: '<div class="views">' +
          '    <div class="view-wrapper" ng-repeat="view in views">' +
          '        <div view="{{view.dir}}"></div>' +
          '    </div>' +
          '</div>',

请注意,我创建了一个新的“view”指令。接下来是视图指令定义,如下所示:

app.directive('view', ['$compile', function (compile) {

    return {
        restrict: 'A',
        scope: {
            view: '@'
        },
        replace: true,   
        template: '<div class="view"></div>',

        controller: ['$scope', function (scope) {
            scope.$watch('view', function (value) {
                scope.buildView(value);
            });
        }],

        link: function (scope, elm, attrs) {

            scope.buildView = function (viewName) {
                var view = compile('<div ' + viewName + '></div>')(scope);
                elm.append(view);
            }
        }
    }
}]);

基本上,view.dir变量作为属性传递给'view'指令,然后该指令监视它的值并用其中的指令编译模板。

答案 1 :(得分:0)

这部分是时间问题......我认为,当它解析{{}}表达式时,它已经被解析出来并呈现了指令。问题本身并不是嵌套或转发器。

然而,你在这里所做的是“根据变量的值确定要呈现的指令”。有几种方法可以做到这一点。

这是一个应该有效的方法,虽然它可能无法像你想的那样扩展:

<div class='views' ng-repeat='view in views'>
  <div ng-switch='view.dir'>
    <div ng-when='my-dir-one' my-dir-one />
    <div ng-when='my-dir-two' my-dir-two />
    <div ng-when='my-dire-three' my-dir-three />
  </div>
</div>

类似技巧的其他选项:看起来您可以使用ngBindTemplate从数据中获取字符串并将其用作元素的模板。这可能会允许一些棘手(和难以辨认)的行为。

您可以将元素的指令指定为类,但我不知道使用ngClass执行此操作是否允许您动态选择指令,或者是否在管道中来得太晚。