AngularJS Tutorial: Benutzerdefinierte Direktiven entmystifizieren

Veröffentlicht: 2022-03-11

Mit dem schnellen Wachstum von JavaScript als Full-Stack-Sprache verwenden immer mehr Anwendungen Frameworks, die es dem Webbrowser ermöglichen, einen größeren Teil der UI-Verarbeitung wie Datenbindung, Verwaltung von Datenansichten, Transformation von Daten und viele andere Dienste zu bewältigen. Eines der leistungsfähigsten, erweiterbarsten und beliebtesten Frameworks ist AngularJS, und eine der nützlichsten Komponenten des AngularJS-Frameworks ist etwas, das als Direktive bezeichnet wird. AngularJS bietet viele nützliche Anweisungen und, was noch wichtiger ist, ein umfassendes Framework zum Erstellen benutzerdefinierter Anweisungen.

Was ist eine Richtlinie? Einfach ausgedrückt sind Direktiven JavaScript-Funktionen, die HTML-DOM-Elemente manipulieren und Verhaltensweisen hinzufügen. Direktiven können sehr einfach oder extrem kompliziert sein. Daher ist es entscheidend, einen soliden Überblick über ihre vielen Optionen und Funktionen zu bekommen, die sie manipulieren.

In diesem Tutorial werden die vier Funktionen, die als Direktive ausgeführt werden, erstellt und auf das DOM angewendet, und es werden Beispiele bereitgestellt. Dieser Beitrag setzt eine gewisse Vertrautheit mit AngularJS und benutzerdefinierten Direktiven voraus. Wenn Sie neu bei Angular sind, wird Ihnen vielleicht ein Tutorial zum Erstellen Ihrer ersten AngularJS-App gefallen.

Die vier Funktionen des Lebenszyklus der AngularJS-Richtlinie

Es gibt viele Optionen, die konfiguriert werden können, und es ist wichtig, wie diese Optionen miteinander in Beziehung stehen. Jede Direktive durchläuft so etwas wie einen Lebenszyklus, während AngularJS das DOM kompiliert und verknüpft. Der Direktiven-Lebenszyklus beginnt und endet innerhalb des Bootstrapping-Prozesses von AngularJS, bevor die Seite gerendert wird. Im Lebenszyklus einer Richtlinie gibt es vier unterschiedliche Funktionen, die ausgeführt werden können, wenn sie definiert sind. Jede ermöglicht dem Entwickler, die Direktive an verschiedenen Punkten des Lebenszyklus zu steuern und anzupassen.

Die vier Funktionen sind: compile , controller , pre-link und post-Link .

Die Kompilierungsfunktion ermöglicht es der Direktive, das DOM zu manipulieren, bevor es kompiliert und gelinkt wird, wodurch es ihr ermöglicht wird, Direktiven hinzuzufügen/zu entfernen/zu ändern sowie andere DOM-Elemente hinzuzufügen/zu entfernen/zu ändern.

Die Controller- Funktion erleichtert die direkte Kommunikation. Geschwister- und Kinderdirektiven können den Verantwortlichen ihrer Geschwister und Eltern auffordern, Informationen zu übermitteln.

Die Pre-Link- Funktion ermöglicht eine private $scope -Manipulation, bevor der Post-Link-Prozess beginnt.

Die Post-Link- Methode ist die primäre Arbeitsmethode der Richtlinie.

In der Direktive findet eine DOM-Manipulation nach der Kompilierung statt, Event-Handler werden konfiguriert, ebenso Watches und andere Dinge. In der Deklaration der Direktive sind die vier Funktionen so definiert.

 .directive("directiveName",function () { return { controller: function() { // controller code here... }, compile: { // compile code here... return { pre: function() { // pre-link code here... }, post: function() { // post-link code here... } }; } } })

In der Regel werden nicht alle Funktionen benötigt. In den meisten Fällen erstellen Entwickler einfach einen Controller und eine Post-Link- Funktion nach dem folgenden Muster.

 .directive("directiveName",function () { return { controller: function() { // controller code here... }, link: function() { // post-link code here... } } })

Link bezieht sich in dieser Konfiguration auf die Post-Link- Funktion.

Unabhängig davon, ob alle oder einige der Funktionen definiert sind, ist ihre Ausführungsreihenfolge wichtig, insbesondere ihre Ausführung relativ zum Rest der AngularJS-Anwendung.

Ausführung der AngularJS-Direktivenfunktion relativ zu anderen Direktiven

Betrachten Sie das folgende HTML-Snippet mit den auf das HTML-Fragment angewendeten Direktiven parentDir , childDir und grandChildDir .

 <div parentDir> <div childDir> <div grandChildDir> </div> </div> </div>

Die Ausführungsreihenfolge der Funktionen innerhalb einer Direktive und relativ zu anderen Direktiven ist wie folgt:

  • Compile-Phase
    • Kompilierfunktion : parentDir
    • Kompilierfunktion : childDir
    • Kompilierfunktion : grandChildDir
  • Controller- und Pre-Link-Phase
    • Controller-Funktion : parentDir
    • Pre-Link-Funktion : parentDir
    • Controller-Funktion : childDir
    • Pre-Link-Funktion : childDir
    • Controller-Funktion : grandChildDir
    • Pre-Link-Funktion : grandChildDir
  • Post-Link-Phase
    • Post-Link-Funktion : grandChildDir
    • Post-Link-Funktion : childDir
    • Post-Link-Funktion : parentDir

Das Tutorial zur AngularJS-Direktivenfunktion – Ausführungsreihenfolge relativ zu anderen Direktiven.

Erläuterung der Funktion der AngularJS-Direktive: Deep Dive

Die Kompilierungsphase tritt zuerst auf. Im Wesentlichen fügt die Kompilierungsphase Ereignis-Listener an die DOM-Elemente an. Wenn beispielsweise ein bestimmtes DOM-Element an eine $scope- Eigenschaft gebunden ist, wird der Ereignis-Listener, der eine Aktualisierung mit dem Wert der $scope- Eigenschaft zulässt, auf das DOM-Element angewendet. Der Kompilierungsprozess beginnt mit dem Root-DOM-Element, von dem aus die AngularJS-Anwendung gebootstrapped wurde, und durchläuft die Zweige des DOM mit einer Tiefendurchquerung, wobei zuerst ein Elternteil und dann seine Kinder bis hinunter zu den Blattknoten kompiliert werden.

Sobald die Kompilierung abgeschlossen ist, können Direktiven nicht mehr zum DOM hinzugefügt oder daraus entfernt werden (obwohl es einen Weg gibt, dies zu umgehen, indem man direkt den Kompilierdienst verwendet. Die nächste Phase ist das Aufrufen von Controllern und Pre-Link-Funktionen für alle Direktiven. Wenn der Controller aufgerufen wird, ist der $scope verfügbar und kann verwendet werden. Das in den Controller eingefügte $-Element enthält die kompilierte Vorlage, enthält jedoch nicht den transkludierten untergeordneten Inhalt (transkludierter Inhalt ist der Inhalt zwischen den Start- und End-HTML-Tags, auf denen sich die Direktive befindet Per Definition übergeben Controller in einem MVC-Muster einfach das Modell an die Ansicht und definieren Funktionen zur Behandlung von Ereignissen.Daher sollte der Controller einer Direktive das DOM der Direktive aus zwei Gründen nicht ändern: Es verletzt den Zweck der Controller, und der transkludierte untergeordnete Inhalt wurde nicht zum DOM hinzugefügt.Was macht ein Controller also, außer den $Scope zu ändern?Der Controller ermöglicht untergeordneten Direktiven, wi zu kommunizieren th übergeordnete Richtlinien. Die Controller-Funktion selbst sollte als ein Controller-Objekt betrachtet werden, das an die Post-Link-Funktion der untergeordneten Direktive übergeben wird, wenn die untergeordnete Direktive dies anfordert. Daher wird der Controller normalerweise verwendet, um die Direktivenkommunikation zu erleichtern, indem ein Objekt mit Eigenschaften und Methoden erstellt wird, die von seinen gleichgeordneten und untergeordneten Direktiven verwendet werden können. Die übergeordnete Direktive kann nicht bestimmen, ob eine untergeordnete Direktive ihren Controller anfordern kann, daher ist es am besten, den Code in dieser Methode auf Funktionen und Eigenschaften zu beschränken, die von untergeordneten Direktiven sicher verwendet werden können.

Nach der Controller-Funktion wird die Pre-Link-Funktion ausgeführt. Die Pre-Link-Funktion ist für viele Leute mysteriös. Wenn Sie viel Dokumentation im Internet und in Büchern lesen, schreiben die Leute, dass diese Funktion nur in seltenen Fällen verwendet wird und die Leute sie fast nie brauchen werden. Dieselben Erklärungen geben dann kein Beispiel für eine Situation, in der es verwendet werden könnte.

Die Pre-Link-Funktion ist wirklich überhaupt nicht kompliziert. Wenn Sie sich zunächst den AngularJS-Quellcode ansehen, werden Sie ein hervorragendes Beispiel für die Pre-Link-Funktion finden: Die Direktive ng-init verwendet sie. Warum? Es ist einfach eine großartige Methode, um privaten Code mit dem $scope auszuführen; Code, der nicht von Geschwister- und Kinddirektiven aufgerufen werden kann. Im Gegensatz zur Controller-Funktion wird die Pre-Link-Funktion nicht in Direktiven übergeben. Daher kann es verwendet werden, um Code auszuführen, der den $Scope seiner Direktive ändert. Die Direktive ng-init macht genau das. Wenn die Pre-Link-Funktion für ng-init ausgeführt wird, führt sie einfach das an die Direktive übergebene JavaScript gegen den $scope der Direktive aus. Das Ergebnis der Ausführung ist durch die prototypische Vererbung von $scope an untergeordnete Direktiven während ihrer Controller-, Pre-Link- und Post-Link-Funktionsausführungen verfügbar, aber ohne Zugriff auf diese untergeordneten Direktiven zu gewähren, um den Code in den übergeordneten Vor-Links erneut auszuführen. Link-Funktion. Außerdem muss die Direktive möglicherweise anderen Code ausführen, der nicht mit dem $Bereich zusammenhängt, den sie privat halten möchte.

Einige erfahrene AngularJS-Entwickler würden sagen, dass dieser private Code immer noch im Controller platziert und dann nicht von den untergeordneten Direktiven aufgerufen werden könnte. Dieses Argument würde gelten, wenn die Direktive nur von dem ursprünglichen Entwickler verwendet wird, der sie codiert hat, aber wenn die Direktive verteilt und von anderen Entwicklern wiederverwendet wird, dann könnte das Einkapseln von privatem Code in die Pre-Link-Funktion sehr vorteilhaft sein. Da Entwickler nie wissen, wie ihre Direktive im Laufe der Zeit wiederverwendet wird, ist das Schützen von privatem Code vor der Ausführung durch eine untergeordnete Direktive ein guter Ansatz für die Kapselung von Direktivencode. Ich halte es für eine gute Praxis, den öffentlichen Code der Direktivenkommunikation in die Controller-Funktion und den privaten Code in die Pre-Link-Funktion zu platzieren. Wie der Controller sollte der Pre-Link niemals eine DOM-Manipulation durchführen oder eine Transclude-Funktion ausführen, da der Inhalt für untergeordnete Direktiven noch nicht verlinkt wurde.

Für jede Direktive werden ihre Controller- und Pre-Link-Funktion vor der Controller- und Pre-Link-Funktion ihrer untergeordneten Direktiven ausgeführt. Sobald die Controller- und Pre-Link-Phase für alle Direktiven abgeschlossen ist, beginnt AngularJS mit der Linking-Phase und führt die Post-Link-Funktionen für jede Direktive aus. Die Linking-Phase verläuft entgegengesetzt zu den Compiler-, Controller- und Pre-Link-Ausführungsabläufen, indem sie mit den Blatt-DOM-Knoten beginnt und sich bis zum Root-DOM-Knoten vorarbeitet. Die Post-Link-DOM-Traversierung folgt größtenteils einem Tiefen-Zuerst-Pfad. Wenn jede untergeordnete Direktive verknüpft ist, wird ihre Post-Link-Funktion ausgeführt.

Die Post-Link-Funktion ist die Funktion, die am häufigsten in benutzerdefinierten AngularJS-Direktiven implementiert wird. In dieser Funktion kann fast alles Sinnvolle getan werden. Das DOM kann manipuliert werden (nur für sich selbst und untergeordnete Elemente), der $scope ist verfügbar, das Controller-Objekt für übergeordnete Direktiven kann verwendet werden, Transclude-Funktionen können ausgeführt werden usw. Es gibt jedoch einige Einschränkungen. Neue Direktiven können dem DOM nicht hinzugefügt werden, da sie nicht kompiliert werden. Darüber hinaus müssen alle DOM-Manipulationen mit DOM-Funktionen durchgeführt werden. Durch einfaches Aufrufen der html- Funktion für das DOM-Element und Übergeben von neuem HTML werden alle Ereignishandler entfernt, die während des Kompiliervorgangs hinzugefügt wurden. Diese funktionieren beispielsweise nicht wie erwartet:

 element.html(element.html());

oder

 element.html(element.html() + "<div>new content</div>");

Der Code bewirkt keine Änderung des HTML-Codes, aber durch die Neuzuweisung der Zeichenfolgenversion der DOM-Elemente werden alle Ereignishandler entfernt, die während des Kompiliervorgangs erstellt wurden. Typischerweise wird die Post-Link-Funktion verwendet, um Event-Handler, $watch es und $observe s zu verbinden.

Sobald alle Post-Link-Funktionen ausgeführt sind, wird der $scope auf die kompilierte und verknüpfte DOM-Struktur angewendet, und die AngularJS-Seite wird lebendig.

Richtlinie Funktionsdiagramm

Hier ist ein Diagramm, das den Zweck jeder Funktion auflistet, was verfügbar ist, wenn sie ausgeführt wird, und Best Practices zur angemessenen Verwendung jeder Funktion.

Ausführung
Befehl
Richtlinie
Funktion
Dom Einschließen $Bereich Abrufbar
von Kind
1 kompilieren DOM wurde nicht kompiliert, aber die Vorlage wurde in den Inhaltsbereich des DOM-Elements geladen. Direktiven können hinzugefügt und entfernt werden. DOM kann sowohl mit DOM-Funktionen als auch mit HTML-String-Ersetzungen manipuliert werden. Die Transclude-Funktion ist verfügbar, aber veraltet und sollte nicht aufgerufen werden. Nicht verfügbar. Funktion kann nicht von untergeordneten Elementen aufgerufen werden.
2 Regler Das kompilierte DOM-Element ist verfügbar, sollte jedoch nicht geändert werden. Eingeschlossener untergeordneter Inhalt wurde dem DOM-Element nicht hinzugefügt. Es sollten keine DOM-Änderungen auftreten, da dies ein Controller ist und transkludierter untergeordneter Inhalt noch nicht verlinkt wurde. Die Transclude-Funktion ist verfügbar, sollte aber nicht aufgerufen werden. $scope ist verfügbar und kann verwendet werden. Funktionsparameter werden mit dem Dienst $injector injiziert. Die Funktion wird an die Verknüpfungsfunktionen der untergeordneten Direktive übergeben und kann von diesen aufgerufen werden.
3 Vorverlinkung Das kompilierte DOM-Element ist verfügbar, sollte jedoch nicht geändert werden, da die DOM-Elemente der untergeordneten Direktive noch nicht eingebunden wurden. Die Transclude-Funktion ist verfügbar, sollte aber nicht aufgerufen werden. $scope ist verfügbar und kann geändert werden. Die Funktion kann nicht von untergeordneten Direktiven aufgerufen werden. Kann aber die Controller übergeordneter Direktiven aufrufen.
4 Postlink Kompilierte DOM-Elemente und DOM-Elemente für untergeordnete Direktiven sind verfügbar. DOM kann nur mit DOM-Funktionen modifiziert werden (kein HTML-Ersatz) und es können nur Inhalte hinzugefügt werden, die keine Kompilierung erfordern. Das Hinzufügen/Entfernen von Direktiven ist nicht erlaubt. Transclude-Funktion ist verfügbar und kann aufgerufen werden. $scope ist verfügbar und kann verwendet werden. Kann nicht von untergeordneten Direktiven aufgerufen werden, kann aber den Controller von übergeordneten Direktiven aufrufen.

Zusammenfassung

In diesem Tutorial zu AngularJS-Direktiven haben wir den Zweck, die Ausführungsreihenfolge und die allgemeinen Fähigkeiten und Verwendungen für jede der vier Direktivenfunktionen kennengelernt: compile , controller , pre-link und post-link . Von den vier Funktionen werden Controller und Post-Link am häufigsten verwendet, aber für komplexere Anweisungen, die eine größere Kontrolle über das DOM benötigen oder eine Ausführungsumgebung für einen privaten Bereich benötigen, können die Funktionen Compile und Pre-Link verwendet werden.