7

I am trying to render a directive inside another directive (not sure if the repeater inside the template is working this), and it seems to just output as text rather than compiling the directive (plunker code here: http://plnkr.co/edit/IRsNK9)

Any ideas on how I can actually get it to render properly my-dir-one, my-dir-two, my-dir-three directives inside the repeater?

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>'
  }
});
4

2 回答 2

8

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

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

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

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

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”指令,然后观察它的值并编译一个包含指令的模板。

于 2013-05-13T09:47:59.557 回答
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 执行此操作是否允许您动态选择指令,或者在管道中是否为时已晚。

于 2013-05-10T15:15:14.547 回答