Unterschied zwischen den Funktionen 'controller', 'link' und 'compile' beim Definieren einer Direktive


393

Einige Orte scheinen die Controller-Funktion für die Direktivenlogik zu verwenden, andere verwenden Link. Das Beispiel für Registerkarten auf der eckigen Homepage verwendet Controller für eine und Link für eine andere Direktive. Was ist der Unterschied zwischen den beiden?


2
Vielleicht ein umfassenderer Überblick über Direktivenfunktionen: Angular-Direktiven - wann Kompilierung, Controller, Pre-Link und Post-Link verwendet werden sollen .
Izhaki

Antworten:


635

Ich werde Ihre Frage ein wenig erweitern und auch die Kompilierungsfunktion einschließen.

  • Kompilierungsfunktion - Verwendung für die DOM-Manipulation von Vorlagen (dh Manipulation von tElement = Template-Element), daher Manipulationen, die für alle DOM-Klone der Vorlage gelten, die der Direktive zugeordnet sind. (Wenn Sie auch eine Verknüpfungsfunktion (oder Funktionen vor und nach der Verknüpfung) benötigen und eine Kompilierungsfunktion definiert haben, muss die Kompilierungsfunktion die Verknüpfungsfunktion (en) zurückgeben, da das 'link'Attribut ignoriert wird, wenn das 'compile'Attribut definiert ist.)

  • Link-Funktion - $watchWird normalerweise zum Registrieren von Listener-Rückrufen (dh Ausdrücken im Bereich) sowie zum Aktualisieren des DOM (dh zum Manipulieren von iElement = einzelnem Instanzelement) verwendet. Es wird ausgeführt, nachdem die Vorlage geklont wurde. Beispielsweise wird in einem <li ng-repeat...>die Verknüpfungsfunktion ausgeführt, nachdem die <li>Vorlage (tElement) für dieses bestimmte <li>Element (in ein iElement) geklont wurde . A $watchermöglicht es einer Direktive, über Änderungen der Bereichseigenschaften informiert zu werden (jeder Instanz ist ein Bereich zugeordnet), wodurch die Direktive einen aktualisierten Instanzwert im DOM rendern kann.

  • Controller-Funktion - muss verwendet werden, wenn eine andere Direktive mit dieser Direktive interagieren muss. Auf der AngularJS-Homepage muss sich die Pane-Direktive beispielsweise selbst zu dem von der Tabs-Direktive verwalteten Bereich hinzufügen. Daher muss die Tabs-Direktive eine Controller-Methode (Think API) definieren, auf die die Pane-Direktive zugreifen / sie aufrufen kann.

    Eine ausführlichere Erläuterung der Registerkarten- und Fensteranweisungen und warum die Registerkartenanweisung eine Funktion auf ihrem Controller mit this(und nicht mit $scope) erstellt, finden Sie unter 'this' vs $ scope in AngularJS-Controllern .

Im Allgemeinen können Sie Methoden $watchesusw. entweder in die Controller- oder die Link-Funktion der Direktive einfügen. Der Controller wird zuerst ausgeführt, was manchmal wichtig ist (siehe diese Geige, die protokolliert, wenn die Funktionen Strg und Link mit zwei verschachtelten Anweisungen ausgeführt werden). Wie Josh in einem Kommentar erwähnt hat , möchten Sie möglicherweise Funktionen zur Manipulation des Bereichs in einen Controller einfügen, um die Konsistenz mit dem Rest des Frameworks zu gewährleisten.


131
Diese Erklärung sollte in den
Hauptdokumenten von

7
Dies ist eine informative Antwort, aber ich denke, dass es schwer zu lesen ist. Vielleicht können mehr Interpunktion und kleinere Sätze helfen. Insgesamt bin ich dankbar für die Antwort.
Marty Cortez

Der $ compiler ignoriert das Attribut 'link', wenn ein Attribut 'compile' vorhanden ist. Aber was ist mit dem Vorhandensein eines "Controller" -Attributs? Verursacht 'controller', dass der $ compiler eines oder beide Attribute 'link' und 'compile' ignoriert? Ist es möglich und / oder ratsam, eine 'Kompilierung' zusammen mit einem 'Controller' zu verwenden?
Carl G

1
@CarlG, das Vorhandensein eines Controller-Attributs hat keine Auswirkungen auf den $ -Compiler in Bezug auf die Verknüpfung und Kompilierung. Sie können Compile und Controller verwenden.
Mark Rajcok

1
"DOM-Listener" sind NICHT "(dh $ watch-Ausdrücke im Bereich)". Einer hört auf das DOM für Ereignisse wie mouseover, der andere auf den Bereich für Eigenschaftsänderungen. Großer Unterschied.
Dmitri Zaitsev

56

Als Ergänzung zu Marks Antwort hat die Kompilierungsfunktion keinen Zugriff auf den Gültigkeitsbereich, die Verknüpfungsfunktion jedoch.

Ich kann dieses Video wirklich empfehlen. Schreiben von Anweisungen von Misko Hevery (dem Vater von AngularJS), in denen er Unterschiede und einige Techniken beschreibt. (Unterschied zwischen Kompilierungsfunktion und Verknüpfungsfunktion um 14:41 Uhr im Video ).


3
+1 für den Link zum Video. Es ist sehr informativ.
Rob Kielty


35
  1. Code vor dem Kompilieren ausführen: Controller verwenden
  2. Ausführen von Code nach der Kompilierung: Verwenden Sie Link

Winkelkonvention: Schreiben Sie Geschäftslogik in Controller und DOM-Manipulation in Link.

Abgesehen davon können Sie eine Controller-Funktion aus der Link-Funktion einer anderen Direktive aufrufen. Zum Beispiel haben Sie 3 benutzerdefinierte Direktiven

<animal>
<panther>
<leopard></leopard>
</panther> 
</animal>

und Sie möchten von innerhalb der "Leoparden" -Richtlinie auf Tiere zugreifen.

http://egghead.io/lessons/angularjs-directive-communication ist hilfreich, um Informationen zur Kommunikation zwischen Richtlinien zu erhalten


18
"Code vor Kompilierung ausführen: Controller verwenden". Das ist falsch; compilewird immer vorher ausgeführt controller.
Izhaki

Sie würden nicht (zumindest nicht auf einfache Weise) über Ihre Leopardenrichtlinie auf Tiere zugreifen können. Untergeordnete Anweisungen können auf Controller-Methoden in einer übergeordneten Direktive zugreifen, aber Geschwister-Direktiven (wie im obigen Beispiel) können die Controller des anderen nicht aufrufen.
Benjamin White

2
Sind Leoparden wirklich eine Art Panther? Nebenbei bemerkt ... Können Sie einen Link - UND - einen Controller in einer Direktive haben?
Cody

1
Ja, Leopard / Jaguare sind Panther. und ja, Sie haben Link und Controller innerhalb der Direktive.
Rahul

1
Aus dem Angular-Entwicklerhandbuch: "Best Practice: Verwenden Sie den Controller, wenn Sie eine API anderen Anweisungen aussetzen möchten. Verwenden Sie andernfalls den Link."
Martin van Driel

6

Kompilierungsfunktion -

  1. wird vor der Controller- und Link-Funktion aufgerufen.
  2. In der Kompilierungsfunktion verfügen Sie über das ursprüngliche Vorlagen-DOM, sodass Sie Änderungen am ursprünglichen DOM vornehmen können, bevor AngularJS eine Instanz davon erstellt und bevor ein Bereich erstellt wird
  3. ng-repeat ist ein perfektes Beispiel - die ursprüngliche Syntax ist ein Vorlagenelement, die wiederholten Elemente in HTML sind Instanzen
  4. Es können mehrere Elementinstanzen und nur ein Vorlagenelement vorhanden sein
  5. Umfang ist noch nicht verfügbar
  6. Die Kompilierungsfunktion kann Funktion und Objekt zurückgeben
  7. Rückgabe einer (Post-Link-) Funktion - entspricht der Registrierung der Link-Funktion über die Link-Eigenschaft des Konfigurationsobjekts, wenn die Kompilierungsfunktion leer ist.
  8. Zurückgeben eines Objekts mit Funktionen, die über Pre- und Post-Eigenschaften registriert wurden - Mit dieser Option können Sie steuern, wann eine Verknüpfungsfunktion während der Verknüpfungsphase aufgerufen werden soll. Informationen zu Vor- und Nachverknüpfungsfunktionen finden Sie weiter unten.

Syntax

function compile(tElement, tAttrs, transclude) { ... }

Regler

  1. wird nach der Kompilierungsfunktion aufgerufen
  2. Umfang ist hier verfügbar
  3. kann von anderen Anweisungen aufgerufen werden (siehe Attribut require)

Pre-Link

  1. Die Link-Funktion ist für die Registrierung von DOM-Listenern sowie für die Aktualisierung des DOM verantwortlich. Es wird ausgeführt, nachdem die Vorlage geklont wurde. Hier wird der größte Teil der Richtlinienlogik platziert.

  2. Sie können den Dom in der Steuerung mit angle.element aktualisieren. Dies wird jedoch nicht empfohlen, da das Element in der Verknüpfungsfunktion bereitgestellt wird

  3. Die Vorverknüpfungsfunktion wird verwendet, um eine Logik zu implementieren, die ausgeführt wird, wenn der Winkel js die untergeordneten Elemente bereits kompiliert hat, jedoch bevor eine der Nachverknüpfungen des untergeordneten Elements aufgerufen wurde

Post-Link

  1. Direktive, die nur Link-Funktion hat, behandelt Angular die Funktion als Post-Link

  2. post wird nach der Kompilierungs-, Controller- und Pre-Link-Funktion ausgeführt. Aus diesem Grund wird dies als der sicherste und standardmäßigste Ort zum Hinzufügen Ihrer Direktivenlogik angesehen

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.