Die Transclude-Option der Direktivendefinition verstehen?


195

Ich denke, dies ist eines der schwierigsten Konzepte, die ich mit der Direktive von anglejs verstehen kann.

Das Dokument von http://docs.angularjs.org/guide/directive lautet:

transclude - Kompiliert den Inhalt des Elements und stellt es der Direktive zur Verfügung. Wird normalerweise mit ngTransclude verwendet. Der Vorteil der Transklusion besteht darin, dass die Verknüpfungsfunktion eine Transklusionsfunktion erhält, die an den richtigen Umfang gebunden ist. In einem typischen Setup erstellt das Widget einen isolierten Bereich, aber die Transklusion ist kein untergeordnetes Element, sondern ein Geschwister des isolierten Bereichs. Auf diese Weise kann das Widget einen privaten Status haben und die Transklusion an den übergeordneten Bereich (vor dem Isolieren) gebunden werden.

  • true - den Inhalt der Richtlinie ausschließen.
  • 'element' - schließt das gesamte Element einschließlich aller Anweisungen mit niedrigerer Priorität aus.

Es heißt transcludetypisch verwendet mit ngTransclude. Das Beispiel aus dem Dokument von ngTransclude verwendet jedoch überhaupt keine ngTranscludeDirektive.

Ich möchte einige gute Beispiele, die mir helfen, dies zu verstehen. Warum brauchen wir es? Was löst es? Wie benutzt man es?


FYI ... Link funktioniert zumindest jetzt
Sandy

Antworten:


518

Stellen Sie sich eine Direktive mit dem Namen myDirective in einem Element vor, und dieses Element enthält einen anderen Inhalt, sagen wir:

<div my-directive>
    <button>some button</button>
    <a href="#">and a link</a>
</div>

Wenn myDirective eine Vorlage verwendet, wird der Inhalt von <div my-directive>durch Ihre Direktivenvorlage ersetzt. Also mit:

app.directive('myDirective', function(){
    return{
        template: '<div class="something"> This is my directive content</div>'
    }
});

führt zu diesem Rendering:

<div class="something"> This is my directive content</div> 

Beachten Sie, dass der Inhalt Ihres ursprünglichen Elements <div my-directive> verloren geht (oder besser gesagt ersetzt wird). Also verabschieden Sie sich von diesen Kumpels:

<button>some button</button>
<a href="#">and a link</a>

Was ist, wenn Sie Ihr <button>...und <a href>...im DOM behalten möchten ? Du brauchst etwas, das Transklusion genannt wird. Das Konzept ist ziemlich einfach: Fügen Sie den Inhalt von einem Ort zum anderen ein . Nun sieht Ihre Direktive ungefähr so ​​aus:

app.directive('myDirective', function(){
    return{
        transclude: true,
        template: '<div class="something"> This is my directive content</div> <ng-transclude></ng-transclude>'
    }
});

Dies würde rendern:

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>. 

Zusammenfassend lässt sich sagen, dass Sie transclude grundsätzlich verwenden, wenn Sie den Inhalt eines Elements beibehalten möchten, wenn Sie eine Direktive verwenden.

Mein Codebeispiel ist hier . Sie könnten auch davon profitieren, wenn Sie dies sehen .


12
Scheint, als hätten sie die Funktionalität ein wenig verändert. Zumindest in Version> = 1.2.9. Der Inhalt der Vorlage wird nicht zum gerenderten Inhalt hinzugefügt. Siehe @ TechExplorer Antwort unten
Tarjei Romtveit

20
Eine sehr, sehr gute Antwort. Weit über dem Normalen. Sie haben gute Beispiele und Ihr "Dies ist mein Direktiveninhalt" machte es sehr einfach, in der gerenderten Version zu lesen. Ich verstehe nicht, warum Angular komplexe Terminologie und Konzepte verwenden muss und dann keine leicht verständlichen Beispiele wie Ihres enthält. +2
freeall

Weiß jemand, ob sich der übertragene Inhalt auf die isolierten Bereichsfelder der Richtlinie beziehen kann? Es heißt oben, dass die Abgeschlossenheit ein Geschwister und kein Kind des isolierten Bereichs ist ... also gehe ich davon aus, dass dies nicht möglich ist - aber ich habe mich gefragt, ob jemand mich bestätigen oder wissen lassen könnte, ob es möglich ist
Simon Green

@UladzimirHavenchyk danke, sie haben das Video an einen anderen Ort verschoben. Ich habe den Link entsprechend repariert.
Odiseo

4
@odiseo, könnten Sie bitte ALLE Angular-Dokumente in einfachem, einfach zu verstehendem Englisch wie diesem schreiben! + viele Einsen.
Dan Hodson

76

Ich denke, es ist wichtig, Änderungen im obigen Verhalten in der neuen Version von AngularJS zu erwähnen. Ich habe eine Stunde lang versucht, mit Angular 1.2.10 die oben genannten Ergebnisse zu erzielen.

Inhalte des Elements mit ng-transclude werden nicht angehängt, sondern vollständig ersetzt.

Im obigen Beispiel würden Sie also mit "transclude" Folgendes erreichen:

<div class="something">
    <button>some button</button>
    <a href="#">and a link</a>
</div>

und nicht

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>

Vielen Dank.


Weitere Informationen zum geänderten Verhalten in Angular 1.2 finden Sie unter change eed299a .
Mark Rajcok

37

Was TechExplorer sagt, ist wahr, aber Sie können beide Inhalte haben, indem Sie ein einfaches Container-Tag (wie div oder span) mit dem Attribut ng-transclude in Ihre Vorlage aufnehmen. Dies bedeutet, dass der folgende Code in Ihrer Vorlage den gesamten Inhalt enthalten sollte

<div class="something"> This is my directive content <div class="something" ng-transclude></div></div>

5
Das war die Schlüsselinformation, die in den anderen Antworten fehlte
Matheus

4
Diese Antwort fügt so viele Informationen hinzu. ng-transcludeist das Attribut, das als Platzhalter fungiert und in dem transkludierter Inhalt platziert wird.
BeingSuman

5

Aus dem Wiki:

"In der Informatik bedeutet Transklusion die Aufnahme eines Teils oder des gesamten elektronischen Dokuments in ein oder mehrere andere Dokumente durch Bezugnahme."

Ich möchte eine weitere Verwendung für die Transklusion hinzufügen, dh die Änderungsreihenfolge der Kompilierungs- und Verknüpfungsfunktionen von übergeordneten und untergeordneten Anweisungen wird geändert. Dies kann nützlich sein, wenn Sie das untergeordnete DOM vor dem übergeordneten DOM kompilieren möchten, da das übergeordnete DOM möglicherweise vom untergeordneten DOM abhängt. Dieser Artikel geht tiefer und verdeutlicht es sehr gut!

http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives-part-2-transclusion/


5

Die aktualisierte Dokumentation zu AngularJS 1.6.6 enthält jetzt eine bessere Erklärung.

Transclude wird verwendet, um eine Direktive zu erstellen, die andere Elemente umschließt

Manchmal ist es wünschenswert, eine ganze Vorlage anstelle einer Zeichenfolge oder eines Objekts übergeben zu können. Angenommen, wir möchten eine "Dialogfeld" -Komponente erstellen. Das Dialogfeld sollte in der Lage sein, beliebigen Inhalt zu verpacken.

Dazu müssen wir die Option transclude verwenden . Siehe das folgende Beispiel.


script.js

angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
  $scope.name = 'Tobias';
}])
.directive('myDialog', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    templateUrl: 'my-dialog.html',
    link: function(scope) {
      scope.name = 'Jeff';
    }
  };
});

index.html

<div ng-controller="Controller">
  <my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>

my-dialog.html

<div class="alert" ng-transclude></div>

Kompilierte Ausgabe

<div ng-controller="Controller" class="ng-scope">
  <my-dialog class="ng-isolate-scope"><div class="alert" ng-transclude="">Check out the contents, Tobias!</div></my-dialog>
</div>

Transclude ermöglicht dem Inhalt einer Direktive mit dieser Option den Zugriff auf den Gültigkeitsbereich außerhalb der Direktive und nicht innerhalb.

Dies ist im vorherigen Beispiel dargestellt. Beachten Sie, dass wir in script.js eine Linkfunktion hinzugefügt haben, die den Namen als Jeff neu definiert. Normalerweise würden wir erwarten, dass {{name}} Jeff ist. In diesem Beispiel sehen wir jedoch, dass die {{name}} -Bindung immer noch Tobias ist.

Best Practice : Nur verwenden, transclude: truewenn Sie eine Direktive erstellen möchten, die beliebigen Inhalt umschließt.


0

transclude: true bedeutet, dass alle in Ihrer Direktive definierten Elemente mit dem Template-Element Ihrer Direktive hinzugefügt werden.

Wenn transclude: false, werden diese Elemente nicht in Ihr endgültiges HTML der Direktive aufgenommen. Es wird nur die Vorlage der Direktive gerendert.

transclude: element bedeutet, dass Ihre Direktivenvorlage nicht verwendet wird. Nur in Ihrer Direktive definierte Elemente werden als HTML gerendert.

Wenn Sie Ihre Direktive definieren, sollte sie auf E beschränkt sein, und wenn Sie sie dann auf Seite hinzufügen

<my-directive><elements><my-directive>
<elements> is like <p>gratitude</p>
what i am talking about.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.