2013-05-10 70 views
7

我想在另一个指令内部渲染一个指令(不知道模板内部的中继器是否在工作),它似乎只是输出为文本而不是编译指令(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>' 
    } 
}); 

回答

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变量被作为对“观看”指令,它然后手表它的值和编译一个模板与它的指令的属性传递。

+0

我还没有发现此解决方案的任何副作用。也就是说,我发现如果预先缓存所有的模板(使用$ templateCache服务),那么您可以在不创建包装元素的情况下离开。 – romiem 2014-01-17 16:23:16

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来做到这一点将允许你动态地选择指令,或者是否在管道中来不及。

+0

根据您的最后一点,将元素指令指定为类不起作用。正如你猜测的那样,绑定过程太晚了。 – 2014-03-02 08:19:26

相关问题