2014-07-04 3 views
6

Was ich tun möchte, ist transcluden von Hand zu handhaben und den Inhalt zu ändern, bevor ich in das DOM einfügen:Wie ändert man den übertragenen Inhalt vor dem Kompilieren in die Direktive?

return { 
    restrict: 'E', 
    transclude: true, 
    template: '<HTML>', 
    replace: true, 
    link: function(scope, element, attrs, ngModelCtrl, $transclude) { 

     var caption = element.find('.caption'); 

     $transclude(function(clone) { 
      console.log(clone); 
      clone.filter('li').addClass('ng-hide'); // this don't work 
      clone.addClass('ng-hide'); // same this one 
      clone.attr('ng-hide', 'true'); // same this one 
      $compile(clone)(scope.$new()).appendTo(caption); 
      caption.find('li').addClass('ng-hide'); // and this 
     }); 
    } 
} 

In Angularjs Quelle ich dieses Beispiel gefunden:

var templateElement = angular.element('<p>{{total}}</p>'), 
     scope = ....; 

    var clonedElement = $compile(templateElement)(scope, function(clonedElement, scope) { 
    //attach the clone to DOM document at the right place 
    }); 

    //now we have reference to the cloned DOM via `clonedElement` 

aber Wenn ich clonedElement.appendTo(caption); innerhalb Link-Funktion hinzufügen, fügen Sie nur einen Kommentar mit ng-Wiederholung innen.

Ich brauche das, weil ich alle Elemente in diesem Fall zu verstecken brauchen

<dropdown> 
    <li ng-repeat="item in items"><a>{{item.label}}</a></li> 
</dropdown> 

Ich brauche die Vorlage zu ändern, bevor kompilieren oder DOM nach ng-repeat erweitert wird. Vorher wäre es besser, weil ich in der Lage sein werde, Logik mit Hilfe der ng-hide-Direktive anstelle der ng-hide-Klasse hinzuzufügen.

Antwort

3

jcubic. Sie müssen $ compile nicht für das verwenden, was Sie tun möchten.

Sie können das übergelagerte Element 'clone' filtern und css-Klassen zu den gefilterten Knoten hinzufügen. Danach müssen Sie jedoch den modifizierten Klon an die Vorlage anhängen .

element.append(clone) 

Ich habe diese jsfiddle für Sie erstellt.

Wenn Sie noch weitere Fragen haben, wenden Sie sich bitte ein jsfiddle Ihrer case.It schaffen wird besser sein, eine Antwort Thx

0

Wenn Sie mit Winkel> 1,3 und ngTransclude in Vorlage zu machen, so dass Sie aktualisieren müssen nicht der Klon, aber transkludiert DOM, zum Beispiel:

elm.find('ng-transclude') 

http://jsfiddle.net/jhqkxgos/

aber sicher sein, zu compile Elemente gefunden, wenn Sie einige aktualisieren Sie vom Controller

zugreifen müssen
3

Ich weiß, dass es lange her ist, seit diese Frage gestellt wurde, aber ich hoffe, dass Sie das Folgende nützlich finden.

Ich war ziemlich lange und schwer in diesem (Transclusion) Geschäft, ich versuchte ein paar Wege, um das zu erreichen, was Sie @jcubic brauchen und schließlich stieß ich auf eine Lösung, die wirklich robust und ziemlich einfach ist.

... 
replace: false, 
transclude: false, 
compile: function(tElement, tAttributes) { 

    // store your "transcluded" content of the directive in the variable 
    var htmlContent = tElement.html(); 
    // then remove it 
    tElement.html(''); 

    return function postLink(scope, elem, attrs) { 
     // then html var is available in your link! 
     var $html = $('<div />',{ html:htmlContent }); // for much easier manipulation (so you can use DOM functions - you can also manipulate directly on htmlContent string) 

     // so you can manipulate the content however you want 
     scope.myVariable = true; 
     $html.find('li').attr('ng-hide', 'myVariable'); // add native directive 
     $html.removeClass('inner-content').addClass('my-inner-content'); // add/remove class 
     $html.find('#myElement').attr('my-directive',''); // add custom directive etc. etc. 

     // after you finished you just need to compile your html and append your directive element - also however you want 
     // you also convert back $html to the string 
     elem.append($compile($html.html())(scope)); // append at the end of element 
     /* or: 
     elem.find('.my-insert-point').html($compile($html.html())(scope)); // append the directive in the specific point 
     elem.find('[my-transclude]').html($compile($html.html())($parent.scope)); // once the scope:true it will be the same as native transclusion ;-) 
     scope.variable = $html.html(); // or you can probably assign to variable and use in your template with bind-html-compile (https://github.com/incuna/angular-bind-html-compile) - may need $sce.trustAsHtml 
     */ 
    } 
} 
... 

So wie Sie Sie haben die volle Kontrolle über Ihre „transkludiert“ Inhalt und Sie brauchen noch nicht einmal Einbindung sehen können! :-)

ps. Ich habe es mit Angular 1.4 getestet. Nicht sicher, ob es mit Ersetzen funktioniert: wahr (ich habe mich nicht darum gekümmert, es zu testen, es ist nur ein kleines Ärgernis, wenn es das nicht tut). Sie können Pre- und Post-Links verwenden, wie Sie normalerweise innerhalb der Compile-Funktion verwenden würden, und Sie müssen $ compile service in Ihre Direktive einfügen.

Verwandte Themen