2013-05-10 9 views
7

Ich versuche eine Direktive innerhalb einer anderen Direktive zu rendern (nicht sicher, ob der Repeater in der Vorlage funktioniert), und es scheint nur als Text ausgegeben zu werden Direktive (Bottom-Code hier: http://plnkr.co/edit/IRsNK9)Rendern Sie eine Direktive innerhalb einer anderen Direktive (innerhalb der Repeater Vorlage)

Irgendwelche Ideen, wie ich es tatsächlich richtig rendern kann, my-dir-eins, meine-dir-zwei, meine-dir-drei Direktiven im 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>' 
    } 
}); 

Antwort

8

konnte ich durch Umschreiben des Codes, um dieses Problem zu umgehen: Hinweis

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

, dass ich eine neue 'view' erstellt:

Zuerst habe ich aktualisiert den Template-Code wie folgt Richtlinie. Als nächstes wird die Richtlinie Definition Ansicht wie folgt:

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

So im Wesentlichen ist die view.dir Variable als Attribut ‚Ansicht‘ Richtlinie verabschiedet, die dann passt es Wert ist und erstellt eine Vorlage mit der Richtlinie darin .

+0

Ich habe keine Nebenwirkungen dieser Lösung gefunden. Das heißt, ich fand heraus, dass wenn Sie alle Vorlagen (mit dem $ templateCache-Dienst) vorab zwischenspeichern, dann können Sie wegkommen, ohne ein Wrapper-Element zu erstellen. – romiem

0

Dieses teil Problem ein Timing ist ... Ich denke, dass es die Lösung der durch die Zeit {{} } Ausdrücke, es ist bereits analysiert und gerendert Anweisungen. Es ist nicht die Verschachtelung oder der Repeater, die per se das Problem darstellen.

Sie wollen hier jedoch entscheiden, welche Anweisung basierend auf dem Wert einer Variablen rendern soll. Es gibt ein paar Möglichkeiten, das zu tun.

Hier ist eine, die funktionieren soll, wenn es nicht so schön könnte skalieren, wie Sie mögen:

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

Weitere Optionen für Ähnliche Tricks: es sieht aus wie Sie ngBindTemplate verwenden könnten eine Zeichenfolge von Daten zu nehmen und verwenden Sie es als Vorlage für ein Element. Dies würde wahrscheinlich ein schwieriges (und unleserliches) Verhalten erlauben.

Sie können eine Direktive für ein Element als eine Klasse angeben, aber ich weiß nicht, ob die Verwendung von ngClass dazu führt, dass Sie die Direktive dynamisch auswählen können, oder ob dies in der Pipeline zu spät kommen würde.

+0

Wie bei Ihrem letzten Punkt funktioniert die Angabe der Anweisung für ein Element als Klasse nicht. Die Bindung kommt zu spät in der Pipeline, wie Sie vermutet haben. –

Verwandte Themen