Die Richtlinie ist eine Möglichkeit, HTML zu lehren, einige neue Tricks zu spielen. Während der DOM -Kompilierung stimmen Richtlinien mit HTML und Execute überein. Dies ermöglicht das Registrierungsverhalten oder die Konvertierung von DOM -Strukturen.
Angular verfügt über eine Reihe integrierter Richtlinien, die sehr hilfreich beim Erstellen einer Web-App sind. Wenn Sie weiter erweitern, können Sie die domänenspezifische Sprache (DSL) in HTML definieren.
1. Zitatanweisungen in HTML
Die Richtlinie hat eine Namensnamen im Kamelgehäuse wie Ngbind (sie scheint in Eigenschaften ~ unbrauchbar zu sein). Die Richtlinie kann jedoch auch mit einem Schlangenbodentyp (Schlangenfall) benannt werden, der durch: (Dickdarm), - (minus) oder _ (Unterstrich) verbunden werden muss. Als optionale Option kann die Anweisung mit "X-" oder "Data-" vorangestellt werden, um die HTML-Überprüfungsanforderungen zu erfüllen. Hier sind die rechtlichen Namen von Richtlinien:
Die Richtlinie kann in Elementnamen, Attributen, Klassen und Kommentaren platziert werden. Das Folgende ist die gleichwertige Art und Weise, Mydir, die Richtlinie, zu zitieren. (Aber viele Richtlinien beschränken sich auf die Verwendung von "Eigenschaften")
<span my-dir = "exp"> </span> <span> </span> <my-dir> </my-dir> <!-Anweisung: my-dir exp->
Die Richtlinie kann auf verschiedene Weise angeführt werden, und die folgenden Listen näquivalente Weise:
<! DocType html> <html Lang = "zh-cn" ng-App> <head> <meta charset = "utf-8"> <titels> invoke-direktes </title> <style type = "text/cs"> .ng-cloak {display: None; · ng_bind = "name" <span ng_bind = "name"> </span> <br/> ng-bind = "name" <span ng-bind = "name"> </span> <br/> data-ng-bind = "name" <span data-bind = "name" x-ng-bind = "name"> </span> <br/> </div> <script src = "../ Angular-1.0.1.js" type = "text/javascript"> </script> <script type } </script> </body> </html>2. String -Interpolation
Während des Kompilierungsprozesses entspricht Compiler den Text mit eingebetteten Ausdrücken in Attributen (wie {{etwas}}) über den $ Interpolat -Dienst. Diese Ausdrücke werden als Uhren registriert und im Rahmen des Digest-Zyklus gemeinsam aktualisiert (war es nicht vorher ein Digest-Schleife?!). Hier ist eine einfache Interpolation:
<img src = "img/{{username}}. JPG"/> Hallo {{Benutzername}}!
3. Zusammenstellungsprozess und Anweisungsübereinstimmung
Drei Schritte zum "Kompilieren" von HTML:
1. Konvertieren Sie zunächst HTML in DOM -Objekte durch die Standard -API des Browsers. Dies ist ein sehr wichtiger Schritt. Weil die Vorlage parserbar sein muss (entspricht den Spezifikationen). Dies kann mit den meisten Vorlagensystemen verglichen werden, die im Allgemeinen auf Zeichenfolgen basieren, nicht auf DOM -Elementen.
2. Die Zusammenstellung des DOM erfolgt durch Aufrufen der $ comple () -Methode. Diese Methode durchquert den DOM und entspricht der Richtlinie. Wenn die Übereinstimmung erfolgreich ist, wird es zusammen mit dem entsprechenden DOM der Richtlinienliste hinzugefügt. Solange alle mit dem angegebenen DOM verbundenen Richtlinien identifiziert werden, werden sie in Priorität sortiert und ihre Compile () -Funktion in dieser Reihenfolge ausführen. Die Richtlinie Compile -Funktion hat die Möglichkeit, die DOM -Struktur zu ändern, und ist für die Erzeugung der Analyse der Link () -Funktion verantwortlich. Die $ compile () -Methode gibt eine kombinierte Verknüpfungsfunktion zurück, bei der eine Sammlung verknüpfter Funktionen enthält, die von der Kompilierfunktion der Anweisung selbst zurückgegeben werden.
3. Schließen Sie die Vorlage über die im vorherigen Schritt zurückgegebene Link -Funktion an den Bereich an. Dadurch werden die eigenen Verknüpfungsfunktion der Richtlinie bezeichnet, sodass sie einige Hörer im Element registrieren und einige Uhren mit Umfang erstellen können. Das Ergebnis darin ist eine zweifache, sofortige Bindung zwischen Umfang und DOM. Wenn sich das Zielfernrohr ändert, erhält das DOM die entsprechende Antwort.
var $ compile = ...; // in Ihren Code injiziert in Ihren Code Var Scope = ...; var html = '<div ng-bind =' exp '> </div>'; // Schritt 1: HTML in DOM -Element var template = angular.element (html) analysieren; // Schritt 2: Kompilieren Sie die Vorlage var linkfn = $ compile (Vorlage); // Schritt 3: Verknüpfen Sie die kompilierte Vorlage mit dem Bereich. linkfn (Scope);
4. Gründe für die Kompilier-/Link -Trennung
Zu diesem Zeitpunkt können Sie sich fragen, warum der Kompilierungsprozess in zwei Schritte unterteilt ist: Kompilieren und Link. Um dies zu verstehen, schauen wir uns ein echtes Beispiel an (Repeater)
Hallo {{user}}, Sie haben folgende Aktionen: <ul> <li ng-Repeat = "Aktion in user.actions"> {{action.description}} </li> </ul>Einfach ausgedrückt, der Grund, warum wir die beiden Kompilierungsschritte und -verbindungen trennen, ist, dass die entsprechende Dom -Struktur manchmal nach der Änderung des Modells geändert werden muss, z. B. Repeater.
Wenn das obige Beispiel kompiliert wird, wird der Compiler alle Knoten iteriert, um die Anweisung zu finden. {{user}} ist ein Beispiel für eine Interpolationsrichtlinie. NGrepeat ist eine weitere Richtlinie. Aber NGrepeat hat Schwierigkeiten. Es erfordert die Fähigkeit, für jede Aktion in Benutzern schnell neues Li zu erstellen. Dies bedeutet, dass um den Zweck des Klonens von Li und die Einbettung spezifischer Aktionen (hier auf einen der Werte der Aktionen des Benutzers) zu erfüllen, eine saubere Kopie des Li -Elements beibehalten, das kloniert und in das UL -Element eingefügt werden muss. Aber das LI -Element zu klonen ist nicht genug. Li muss auch zusammengestellt werden, damit seine Anweisung ({{action.descriptions}}) im richtigen Bereich analysiert werden kann. Die ursprüngliche Methode fügt im Allgemeinen einfach eine Kopie des Li -Elements ein und kompiliert sie dann. Das Kompilieren von Kopien jedes Li -Elements ist jedoch langsamer, da der Kompilierungsprozess erfordert, dass wir den DOM -Knotenbaum durchqueren, Anweisungen finden und ausführen. Wenn wir ein Kompilieren haben, das 100 Elemente über Repeater verarbeiten muss, werden wir mit Leistungsproblemen festhalten.
Die Lösung für das Problem besteht darin, den Kompilierungsprozess in zwei Schritte zu zerlegen. Die Kompilierstufe erkennt alle Richtlinien an und sortiert sie nach Priorität, wodurch ein bestimmtes Anwendungsbereich während der Verknüpfungsstufe mit einem bestimmten Li verbindet.
NGrepeat erstellt individuelle LIs separat, um zu verhindern, dass der Kompilierungsprozess in Li -Elemente fällt. Das Kompilierungsergebnis des Li -Elements ist eine Richtlinieverknüpfungsfunktion, die alle im Li -Element enthaltenen Richtlinien enthält und bereit ist, sich mit der Kopie des spezifischen Li -Elements zu verbinden. Zur Laufzeit überwacht NGrepeat den Ausdruck und wird als Element zu einer Reihe von Li -Elementen -Kopien hinzugefügt, wodurch ein neuer Bereich für die klonierten Li -Elemente erstellt und die Linkfunktion aufgerufen wird, die der Kopie entspricht.
Zusammenfassen:
1. Kompilierungsfunktion - Kompilierungsfunktionen sind in Richtlinien relativ selten, da sich die meisten Richtlinien nur darum kümmern, mit bestimmten DOM -Elementen zu arbeiten, anstatt die Vorlagen der DOM -Elemente (DOM selbst und seine interne Struktur) zu ändern. Um die Leistung zu optimieren, können einige Vorgänge, die von Richtlinieninstanzen gemeinsam genutzt werden können, in die Kompilierungsfunktion verschoben werden.
2. Linkfunktion - Nur sehr wenige Anweisungen haben keine Linkfunktion. Mit der Linkfunktion kann die Anweisung einen Listener in der angegebenen Kopie der DOM -Elementinstanz registrieren oder spezifische Inhalte aus dem Geltungsbereich in die DOM kopieren.
5. Schreiben Sie eine Richtlinie (einfache Version)
In diesem Beispiel erstellen wir eine Richtlinie, die die aktuelle Zeit gemäß dem Eingabeformat anzeigt.
<! DocType html> <html lang = "zh-cn" ng-app = "timeFormat"> <head> <meta charset = "utf-8"> <title> time-format </title> </head> <body> <div ng-controller = "myctrl" id = "Main"> "Main"> "Main"> "Main"> "Main"> "Main"> < Typ = "text"/> <hr/> <! --> Current time is : <span x-current-time="format" id="myFormat"></span><br/> <button ng-click="remove()">remove the span</button></div><script src="../angular-1.0.1.js" type="text/javascript"></script><script type = "text/javaScript"> angular.module ("timeFormat", []) // Registrieren Sie die Richtlinienfabrikmethode "CurrentTime" in der TimeFormat -Anwendung // Wie oben erwähnt, kann die Abhängigkeitsinjektion direkt in die Funktionsparameter geschrieben werden, hier in die Funktionsparameter, die hier injiziert wurde, $ Timeout und Datenfilter .Directive. Kompilienfunktion, warum? ... Rückgabefunktion (Umfang, Element, Attr) {var intervalid; SCOPE. $ Watch (attr.CurrentTime, function (value) {scope.format = value; updatetime ();}); }). Controller ("myctrl", function ($ scope, $ rootscope) {$ scope.format = "m/d/yy h: mm: ss a"; Das Ereignis von $ Destrey kann es ausgelöst werden!6. Schreiben Sie eine Richtlinie (detaillierte Version)
Im Folgenden finden Sie eine Beispielerstellung einer Richtlinie (Richtlinie -Objektdefinitionsvorlage). Wenn Sie die detaillierte Liste sehen möchten, lesen Sie bitte weiter.
var mymodule = angular.module (...); myModule.directive('directiveName', function factory(injectables) { var directiveDefinitionObject = { priority: 0, template: '<div></div>', templateUrl: 'directive.html', replace: false, transclude: false, restrict: 'A', scope: false, compile: function compile(tElement, tAttrs, transclude) { return { pre: function Prelink (Scope, Ielement, iattrs, Controller) {...}, post: Funktion postlink (Scope, Ielement, iattrs, Controller) {...}}, Link: Funktion postlink (Scope, Ielement, iattrs) {...}};In den meisten Szenarien benötigen wir keine genaue Kontrolle, sodass die obige Definition vereinfacht werden kann. Das Definieren jedes Teils der Vorlage wird im folgenden Kapitel erläutert. In diesem Kapitel konzentrieren wir uns nur auf Isomere dieses Skeletts, die die Vorlage definieren (Isomere dieses Skeletts, ich verstehe nicht ... Ich freue mich auf die Ergänzung aller).
Der erste Schritt zur Vereinfachung Ihres Codes besteht darin, sich auf Standardwerte zu verlassen. Daher kann der obige Code vereinfacht werden zu:
var mymodule = angular.module (...); myModule.directive ('Directivename', Funktionsfabrik (Injectable) {var DirectiveIntEFinitionObject = {Compile: Funktion Compile (telement, tattrs) {return function postlink (scope, iElement, ielement, iattrs) {...}}; returnivedEfinitionObject;});Die meisten Richtlinien kümmern sich nur um Instanzen, keine Vorlagenkonvertierung, sodass sie weiter vereinfacht werden können (übersetzt sehr hart ... freuen uns auf die Ergänzung aller):
var mymodule = angular.module (...); myModule.directive ('Directiveame', Funktionsfabrik (Injectable) {Rückgabefunktion Postlink (Scope, Ielement, iattrs) {...}});7. Fabrikmethode
Die Fabrikmethode ist für die Erstellung von Richtlinien verantwortlich. Es wird nur einmal verwendet, genau dann, wenn der Compiler die Richtlinie zum ersten Mal entspricht. Hier können Sie einige Initialisierungsvorgänge durchführen. Die Fabrikmethode wird über $ injector.invoke ausgeführt, sodass sie allen Regeln für Injektionserklärung (Annotation von Injektionsregeln) entspricht, sodass sie injizierbar ist.
8. Direktive Definition Objekt Beschreibung
Richtliniendefinitionsobjekte liefern die Compiler -Struktur. Die Eigenschaften sind wie folgt:
1.Name - Der Name des aktuellen Umfangs. Der Standardwert kann bei der Registrierung verwendet werden (nicht ausgefüllt).
2. PRIURITY- Wenn mehrere Anweisungen im selben DOM-Element definiert sind, müssen manchmal ihre Ausführungsreihenfolge klären. Diese Eigenschaft wird verwendet, um vor dem Aufruf der Richtlinie zu sortieren. Wenn die Priorität gleich ist, ist die Ausführungsreihenfolge ungewiss (nach vorläufigen Experimenten werden zuerst diejenigen mit höherer Priorität ausgeführt, und das gleiche Niveau ähnelt der "Nachbindung" Ausführung zuerst ". Außerdem war ich während des Tests ein wenig nachlässig. Bei der Definition der Richtlinie mit demselben Namen wurde zweimal definiert, aber die Ausführungsergebnisse, die sowohl Kompensationen als auch die Link zu linken, oder die Link oder die Link, oder das Link oder die Link, oder die Link, oder die Link, oder die Link, oder die Link, oder die Link oder die Link, oder die Link, oder die Link, oder die Link oder die Link, oder die Link, werden die Link oder die Link zu verkleinern.
3.terminal (letzte Gruppe) - Wenn auf "True" eingestellt ist, wird die aktuelle Priorität zur Richtlinie der letzten Gruppe der Ausführung werden. Wenn eine Richtlinie der aktuellen Priorität übereinstimmt, wird sie weiterhin ausgeführt, aber die Reihenfolge ist ungewiss (obwohl die Reihenfolge ungewiss ist, ist sie im Grunde genommen der Reihenfolge der Priorität. Nachdem die aktuelle Priorität ausgeführt wurde, wird eine niedrigere Priorität nicht erneut ausgeführt).
4.Scope - Wenn auf:
1) .True - Für diese Anweisung wird ein neuer Bereich erstellt. Wenn es in demselben Element mehrere Anweisungen gibt, die einen neuen Bereich erfordern, erzeugt es immer noch einen Bereich. Die neuen Umfangsregeln gelten nicht für die Stammvorlage, sodass die Stammvorlage tendenziell einen neuen Bereich erhält.
2). {} (Objekt Hash) - Ein neuer Isolatbereich wird erstellt. Der Unterschied zwischen "Isolat" -Amgum und allgemeinem Umfang besteht darin, dass er nicht durch Prototypen aus dem Elternbereich geerbt wird. Dies ist sehr hilfreich für die Erstellung wiederverwendbarer Komponenten und kann effektiv das Lesen oder Ändern von Daten aus dem übergeordneten Bereich verhindern. Dieser unabhängige Bereich erstellt einen Objekt -Hash mit einer Reihe lokaler Bereichseigenschaften, die aus dem übergeordneten Bereich abgeleitet sind. Diese lokalen Eigenschaften sind nützlich für Aliasing -Werte für Vorlagen -_-!. Die Definition der Einheimischen ist ein Hash of Local Scope -Eigenschaft für die Quelle#&) $ &##) ($ &@#_):
3). @ Oder @attr - Erstellen Sie eine lokale SCOPE -Eigenschaft für die DOM -Eigenschaft. Da der Eigenschaftswert immer String -Typ ist, gibt dieser Wert immer eine Zeichenfolge zurück. Wenn der Attributname nicht über @Attr angegeben wird, wird der lokale Name immer mit dem Namen des DOM -Attributs erfolgt. Zum Beispiel <Widget my-attr = ”Hallo {{{name}}"> ist der Umfang des Widgets definiert als: {localname: '@myattr'}. Anschließend wird der Lokalname der Widget Scope -Eigenschaft den realen Wert zuordnen, der von "Hallo {{Name}}" konvertiert wird. Nachdem sich der Namensattributwert ändert, ändert sich auch das Lokalname-Attribut des Widget-Umfangs entsprechend (nur einseitig, unterscheidet sich von der folgenden "="). Das Namensattribut wird im übergeordneten Bereich gelesen (nicht im Komponentenbereich)
4). Wenn der ATT -Name nicht angegeben ist, stimmt der lokale Name mit dem Attributnamen überein. Zum Beispiel ist <Widget my-attr = ”parentModel”>, das von Widget definierte Bereich lautet: {localModel: '= myattr'}, die Widget Scope-Eigenschaft. Wenn Änderungen in ParentModel auftreten, ändert sich auch Lokalmodel und umgekehrt. (Bi-Way-Bindung)
5). Wenn der ATT -Name nicht angegeben ist, stimmt der lokale Name mit dem Attributnamen überein. Zum Beispiel wird <Widget my-attr = ”count = count + value”> das Widget-Umfang definiert als: {localFn: 'Increment ()'}, dann zeigt die SCOPE-Eigenschaft "localfn" auf eine Funktion, die mit einem Increment () -Ausdruck eingeschlossen ist. Im Allgemeinen möchten wir Daten aus dem Isolatbereich an den übergeordneten Bereich durch einen Ausdruck übergeben. Dies kann durch Übergeben einer Karte des Schlüsselwerts einer lokalen Variablen in die Wrapper -Funktion des Ausdrucks erfolgen. Wenn der Ausdruck beispielsweise Inkrement (Betrag) ist, können wir LocalFn über LocalFn ({Betrag: 22}) aufrufen, um den Wert des Betrags anzugeben (das obige Beispiel versteht wirklich nicht und wohin sind Sie gegangen?).
5.Controller - Controller -Konstruktor. Der Controller initialisiert vor dem Vorverknüpfungsschritt und erlaubt, dass andere Anweisungen über den erforderlichen mit dem angegebenen Namen teilen (siehe die erforderliche Eigenschaft unten). Auf diese Weise können Anweisungen miteinander kommunizieren und gegenseitiges Verhalten verbessern. Der Controller injiziert standardmäßig die folgenden lokalen Objekte:
1). $ Scope - Umfang kombiniert mit dem aktuellen Element
2) $ Element - aktuelles Element
3) $ attrs - das Attributobjekt des aktuellen Elements
4). (Eine Transclude-Verknüpfungsfunktion, die vor dem richtigen Übersetzungsbereich vorgebunden ist)
6. Erfordernis - fordern Sie einen anderen Controller an, ihn in die aktuelle Richtlinieverknüpfungsfunktion zu übergeben. verlangen, dass der Name eines direkten Controllers übergeben wird. Wenn der diesem Namen entsprechende Controller nicht gefunden werden kann, wird ein Fehler geworfen. Der Name kann mit Folgendem vorangestellt werden:
1).? - Wirf keine Ausnahmen. Dies macht diese Abhängigkeit zu einer Option.
2).^ - Ein Controller, der die Suche nach übergeordneten Elementen ermöglicht
7.RESTRICT - Eine Zeichenfolge einer Teilmenge von EACM, die die Anweisung auf die angegebene Deklarationsmethode einschränkt. Wenn es weggelassen wird, erlaubt die Richtlinie nur Deklarationen über Attribute:
1) E-Elementname: <my-directive> </my-directive>
2) .A - Attributname: <div my -directive = ”exp”> </div>
3). C - Klasse Name: <div class = "my -directive: exp;"> </div>
4) .m-Kommentar: <!-Richtlinie: My-Directive Exp->
8. Template - Wenn ersetzt ist, ersetzen Sie den Vorlageninhalt durch das aktuelle HTML -Element und migrieren Sie die Attribute und die Klasse des ursprünglichen Elements. Wenn falsch, wird das Vorlagenelement als untergeordnetes Element des aktuellen Elements behandelt. Weitere Informationen finden Sie im Kapitel "Widgets erstellen" (wo ... Komponenten erstellen können ...)
9.Templateurl - ist im Grunde genommen die gleiche wie die Vorlage, aber die Vorlage wird durch die angegebene URL geladen. Da die Vorlagebelastung asynchron ist, wird die Kompilierung und Verknüpfung pausiert und nach dem Laden ausgeführt.
10. Replace - Wenn auf TRUE eingestellt ist, ersetzt die Vorlage das aktuelle Element, anstatt dem aktuellen Element als untergeordnetes Element hinzugefügt zu werden. (Hinweis: Wenn wahr, muss die Vorlage einen Stammknoten haben)
11. TRANSCLUDE - Kompilieren Sie den Inhalt eines Elements so, dass es nach der Richtlinie verwendet werden kann. Erforderlich (in der Vorlage), die verwendet werden soll (referenziert). Der Vorteil der Transklusion besteht darin, dass die Verknüpfungsfunktion eine Übersetzungsfunktion erhalten kann, die vor dem aktuellen Bereich vorgebunden ist. Erstellen Sie im Allgemeinen ein Widget und erstellen Sie einen Isolatbereich. Übersetzung ist kein Kind, sondern ein Bruder des Isolatsbereichs. Dadurch wird das Widget einen privaten Zustand haben und die Transklusion wird an den übergeordneten (vor-isolierten) Bereich gebunden. (Ich verstehe den obigen Absatz nicht. Aber in tatsächlichen Experimenten wird Mydirective durch <irgendein My-Direktor> {{name}} </irgendein my-direktes> und der Transkluden auf wahr eingestellt oder eine Zeichenfolge und die Vorlage enthält <irgendwann ng-transclude>, wodurch die Inhalte von {name}}}}}}}}}}}}}}}}} enthält. Seien Sie eine zusätzliche Zeitspanne in der Zeit.
1) .True - Konvertieren Sie den Inhalt dieser Richtlinie. (In diesem Sinne soll der Inhalt direkt zusammengestellt und an den angegebenen Ort verschoben werden)
2). 'Element' - Konvertiert das gesamte Element, einschließlich anderer Richtlinien mit niedrigerer Priorität. (Zum Beispiel wird nach dem Kompilieren des gesamten Inhalts als Ganzes (draußen P P gepackt) behandelt und in den angegebenen Ort eingeführt)
12.comPile - Hier ist die Kompilierungsfunktion, die in den folgenden Kapiteln ausführlich erläutert wird
13.Link - Hier ist die Linkfunktion, die im folgenden Kapitel ausführlich erläutert wird. Diese Eigenschaft wird nur verwendet, wenn die Kompilierungseigenschaft nicht definiert ist.
9. Kompilierungsfunktion
Funktionskompile (Telement, Tattrs, transklude) {…}
Die Kompilierungsfunktion wird verwendet, um die Konvertierung von DOM -Vorlagen zu verarbeiten. Da für die meisten Richtlinien keine Konversionsvorlagen erforderlich sind, wird das Kompilieren nicht häufig verwendet. Richtlinie, die eine Kompilierungsfunktion erfordert, im Allgemeinen solche, die DOM -Vorlagen (z. B. NGrepeat) konvertieren müssen, oder solche, die Inhalte asynchron laden müssen (z. B. NGView). Die Kompilierungsfunktion hat die folgenden Parameter:
1.Telement - Das Vorlagenelement verwendet das aktuelle Richtlinieelement. Es ist sicher, nur die Vorlagenkonvertierung unter dem aktuellen Element oder dem aktuellen Element untergeordnetes Element durchzuführen.
2.TATTRS - Vorlagenattribute - standardisierte Attribute, die im aktuellen Element deklariert sind, können unter verschiedenen Richtlinien geteilt werden. Weitere Informationen finden Sie im Kapitel Attribute
3. Übertragen Sie eine Verknüpfungsfunktion für die Konvertierung: Funktion (Umfang, Klonelinkum).
Hinweis: Wenn die Vorlage kloniert wurde, kann die Vorlageninstanz und die Linkinstanz nicht dasselbe Objekt sein. Dazu ist es nicht sicher, etwas anderes als die DOM -Konvertierung in der Kompilierungsfunktion durchzuführen, die auf alle Klone angewendet wird. Insbesondere der Registrierungsbetrieb des DOM -Ereignishörers sollte in der Verknüpfungsfunktion und nicht in der Kompilierungsfunktion durchgeführt werden.
Die Kompilierungsfunktion kann einen Rückgabewert haben und der Typ kann Funktion oder Objekt sein.
1. Die Rückgabefunktion wird normalerweise verwendet, wenn die Kompilierungsfunktion nicht erforderlich ist (leer), was der Registrierung einer Verknüpfungsfunktion über Link entspricht (definiert direkt die Attribute der Vorlage).
2. Gibt ein Objekt zurück, das vor und nach dem Eigenschaften enthält - ermöglicht es uns, die Verknüpfungsfunktion während der Verknüpfungsphase zu steuern. Weitere Informationen finden Sie in den folgenden Kapiteln über Vorverknüpfungs- und Nachverbindungsfunktionen.
10. Verbindungsfunktion
Funktionslink (Scope, Ielement, Iattrs, Controller) {…}
Die Linkfunktion ist für die Registrierung des DOM -Event -Listeners verantwortlich und kann auch DOM -Update -Vorgänge ausführen. Die Linkfunktion wird ausgeführt, nachdem der Vorlagenklonierungsvorgang abgeschlossen ist. Der größte Teil der Logik der Richtlinie wird hier gespeichert.
1.Scope - Scope - wird verwendet, um Uhren zu registrieren (http://docs.angularjs.org/api/ng.$rootscope.scope#$Watch).
2.ielement - Elementinstanz - Element, das von der Richtlinie verwendet wird. Es ist sicher, unter Kinderelementen in der Postlink -Funktion zu arbeiten. Weil die Kinderelemente verknüpft sind (mit dem Modell verbunden sind?!).
3.Ittrs - Attributinstanz - Die Attributliste des Standardstromelements. Geteilt zwischen allen Richtlinienverbindungsfunktionen.
4.Controller - Controller -Instanz - Wenn einer der Controller in der Richtlinie des aktuellen Elements definiert ist, können Sie hier eine Instanz des Controllers erhalten. Dieser Controller wird unter allen Richtlinien geteilt, sodass jede Richtlinie den Controller als Kommunikationskanal zwischen ihnen behandelt.
Vorverbindung
Vor dem verknüpften untergeordneten Element ausführen. Hier ist es nicht sicher, die DOM -Konvertierung durchzuführen, da die Verknüpfungsfunktion des Compiler beim Verknüpfen möglicherweise nicht die richtigen Elemente lokalisiert.
Post-Link-Funktion
Ausführen nach dem verknüpften untergeordneten Element. Es ist sicher, hier DOM -Conversion durchzuführen.
11. Attribute
Attributobjekt - als Argumente in link () oder compile () - ist eine Möglichkeit, auf die folgenden zuzugreifen:
1. Standardisierte Attributnamen: Weil die Richtlinie wie ngbind in vielen Formen manifestiert werden kann, z.
2. Kommunikation zwischen Richtlinien: Alle Richtlinien teilen eine Attributobjektinstanz, sodass Richtlinien zwischen den Attributobjekten zwischen Richtlinien kommunizieren können.
3. Support Interpolation: Das Interpolationsattribut wird einem Attributobjekt zugewiesen, sodass andere Anweisungen den interpolierten Wert lesen können.
4. Beobachten Sie interpolierte Attribute: Beobachten Sie Änderungen der Attributwerte durch Attr. $ Beobachten, einschließlich Interpolation (z. B. Src = ”{{bar}}“). Es ist nicht nur sehr effektiv, sondern auch die einzige Möglichkeit, einfach den wahren Wert zu erhalten. Da während der Verknüpfungsphase die Interpolation nicht zugewiesen wurde (ersetzt durch den realen Wert). Wenn Sie also zu diesem Zeitpunkt darauf zugreifen, ist das Ergebnis undefiniert.
<! DocType html> <html Lang = "zh-cn" ng-App = "DirectiveProperty"> <head> <meta charset = "utf-8"> <title> Directive-Attribute-Test </title> <style type = "text/css"> .ng-clakak {display: keine; " type = "text/javaScript"> </script> <script type = "text/javaScript"> var app = angular.module ("DirectiveProperty", []); app.Controller ("myctrl", function ($ scope) {$ scope.name = "my Little Dada";}); var DirectiveP2 = app.directive ("DirectiveP2", function () {return {link: function postlink (scope, lele, lattr) {console.log ("MyAttr:" + lattr.myattr); // 123 console.log ("myattr: attddddddddddddddddddddddddddddddddddddddd. console.log ('attrdd hat den Wert auf' + Wert geändert);12. Verstehe Transclusion und Umfang
Wir brauchen oft einige wiederverwendbare Komponenten. Hier ist ein Pseudo-Code, der zeigt, wie eine einfache Dialogkomponente funktionieren kann.
<button ng-klick = "show = true"> show </button> <dialog saciible = "show" on-cancel = "show = false" on-ok = "show = false; doSomething ()"> Body geht hierher: {{{Benutzername}} ist {{title}}. </dialog> dialog> dialog> dialog> dialog> dialog>Durch Klicken auf die Schaltfläche "anzeigen" wird das Dialogfeld geöffnet. Der Dialog enthält einen Titel, der an die Daten "Benutzername" gebunden ist, und es gibt auch einen Absatz, den wir im Dialog stellen möchten.
Das Folgende ist eine Vorlagendefinition, die für den Dialogfeld geschrieben wurde:
<div ng-show = "show ()"> <h3> {{title}} </h3> <div ng-transclude> </div> <div> <button ng-klick = "onok ()"> Änderungen speichern </button> <button ng-klickDies wird nicht korrekt erledigt, es sei denn, wir machen eine besondere Behandlung im Bereich.
Das erste Problem, das wir lösen müssen, ist, dass die Dialogvorlage erwartet, dass der Titel definiert wird und bei der Initialisierung an den Benutzernamen gebunden wird. Darüber hinaus erfordert die Taste zwei Funktionen Onok und Oncancel, um im Bereich zu erscheinen. Dies begrenzt die Nützlichkeit des Widgets ..). Um das Mapping -Problem zu lösen, werden die von der Vorlage erwarteten lokalen Variablen von den folgenden lokalen Methoden erstellt (Einheimische, die als Umfang der Anweisungsdefinitionsvorlage geschätzt werden):
SCOPE: {Titel: 'Bind', // Title einrichten, um datenbindende ONOK: 'Ausdruck', // Erstellen einer Delegierten-Onok-Funktion Oncancel: 'Ausdruck', // Erstellen einer Delegierten-Oncancel-Funktion: 'Accessor' // Erstellen einer Getter/Setter-Funktion zur Sichtbarkeit.}Das Erstellen lokaler Eigenschaften im Kontrollbereich bringt zwei Probleme mit sich:
1. Isolation (Attribut -Isolation?) - Wenn der Benutzer vergisst, den Elementattributtitel in der Kontrollvorlage festzulegen, wird der Titel an den Attribut "Titel" des Vorfahren (falls vorhanden) gebunden. Dies ist unvorhersehbar und unerwünscht.
2. Transclusion - Translated DOM kann die Einheimischen (Isolatbereich?) Der Kontrolle anzeigen. Die Einheimischen überschreiben die Eigenschaften, die wirklich in der Transklearie gebunden werden müssen. In unserem Beispiel zerstört die Titeleigenschaft im Plugin die Titeleigenschaft der Transklusion.
Um dieses Problem des Mangels an Attributisolation zu lösen, müssen wir einen isolierten Bereich für diese Richtlinie definieren. Isolierter Bereich wird nicht aus dem Prototyp aus dem Kinderbereich geerbt (warum ist es Kinderumfang? Ist es nicht übergeordnete Bereiche?).
Das isolierte Bereich bringt jedoch ein neues Problem mit sich: Wenn ein übersetzter DOM ein Kind des isolierten Widget -Bereichs ist, kann es an nichts in irgendetwas binden. Daher ist das übersetzte Umfang ein untergeordneter Bereich des ursprünglichen Bereichs, das er erstellt hat, bevor die Kontrolle den isolierten Bereich für die lokale Eigenschaft erstellt. Das übersetzte und der isolierte Bereich gehören zum Geschwisterknoten (im Bereichsbereich).
Dies mag etwas unerwartet kompliziert erscheinen, aber dies bringt zumindest Überraschungen, um Benutzer zu kontrollieren und Entwickler zu steuern. (Das Problem wurde gelöst)
Daher ist die endgültige Direktivdefinition ungefähr wie folgt:
transklude: true, scope: {title: 'bind', einrichten up title, um data-binding onok: 'expression', // Erstellen einer Delegierten-Onok-Funktion Oncancel: 'Ausdruck', // Erstellen einer Delegierten-Oncancel-Funktion: 'Accessor' // Erstellen Sie eine Getter/Setter-Funktion für die Sichtbarkeit. // Ich habe es versucht, aber es ist fehlgeschlagen ... Bitte lesen Sie weiter}Ich habe versucht, den obigen Code in ein vollständiges Beispiel zusammenzustellen. Wenn Sie direkt kopieren, werden die erwarteten Ergebnisse nicht erzielt. Nach ein wenig Modifikation kann das Plug-In ausgeführt werden.
<! DocType html> <html ng-App = "Dialog"> <Head> <meta http-äquiv = "content-type" content = "text/html; charset = utf-8"/> <title> Directive-Dialog </title> <meta-content = "ie =" kande, chrome = http-äik "· ie =" src = "../ angular.js" type = "text/javaScript"> </script> </head> <body> <div ng-controller = "myctrl"> <button ng-klick = "show = true"> show </button> <dialog scisible = "{{{{{show}}}" On-OK = "show = false; methodInparentScope ();"> <!-Das obige On-Corne und On-OK werden durch & in der Richtlinie Isoloate-Umfang verwiesen. Wenn der Ausdruck eine Funktion enthält, müssen Sie die Funktion im übergeordneten Bereich binden (derzeit myctrl cecope) -> Körper geht hierher: Benutzername: {{Benutzername}}, Titel: {{Titel}}. <ul> <!-Sie können hier auch hier spielen ~ Namen ist übergeordnete Scope-> <li ng-Repeat = "Name in Namen"> {{name}} </li> </ul> </dialog> </div> <script type = "text/javascript"> var mymodule = Angular.module ("Dialog", []; MYMODULE.CONTROLLER ("myctrl", function ($ scope) {$ scope.names = ["name1", "name2", "name3"]; im übergeordneten Bereich gespielt !!! ");};}); myModule.directive ('Dialog', function Factory () {return {Priority: 100, Vorlage: ['<div ng-show = "sichtbar">', '<H3> {{{title}} </h3>', '<div ng-transclude ng-klick = "oncancel ()"> close </button> ',' </div> ',' </div> ',' </div> ']. join (""), ersetzen: false, transclude: wahr, einschränken:' E ', Scope: {Titel: "@", // Zitieren Sie den Wert des Titels des Titel-Attributs des Dialog-Dialog-Tags. Die Form der Wrapper-Funktion Oncancel: "&", // Verwenden Sie die Wrapper-Funktionsform auf den Inhalt der On-Cancel-Eigenschaft des Dialog-Tags sichtbar: "@" // bezieht sich auf den Wert der sichtbaren Eigenschaft des Dialog-Tags}}); </script> </body> </html>13. Komponenten erstellen
Wir erwarten normalerweise, die Richtlinie durch eine komplexe DOM -Struktur zu ersetzen (das Element befindet sich? Dadurch wird eine Verknüpfung zum Bau von Anwendungen mit wiederverwendbaren Komponenten zur Verfügung gestellt.
Hier ist ein Beispiel für eine wiederverwendbare Komponente:
<!DOCTYPE html><html ng-app="ZippyModule"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>ZippyModule</title> <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> <style type = "text/css"> .zippy {border: 1px solid schwarz; Anzeige: Inline-Block; Breite: 250px; } .zippy.opened> .title: vor {content: ''; } .zippy.opened> .body {display: block; } .zippy.closed > .title:before { content: '► '; } .zippy.closed > .body { display: none; } .zippy > .title { background-color: black; color: white; padding: .1em .3em; cursor: pointer; } .zippy > .body { padding: .1em .3em; } </style> <script src="../angular.js" type="text/javascript"></script></head><body> <div ng-controller="MyCtrl"> Title: <input ng-model="title" type="text"><br/> Text: <textarea ng-model="text"></textarea> <hr/> <div zippy-title="Details: {{title}}...">{{text}}</div> </div> <script type="text/javascript"> var myModule = angular.module("ZippyModule", []); myModule.controller("MyCtrl", function ($scope) { $scope.title = "Here is the title"; $scope.text = "Here is the content... "; }); myModule.directive('zippy', function () { return { template: '<div>' + ' <div>{{title}}</div>' +//This title belongs to the property of the current direct isolate scope ' <div ng-transclude></div>' + //What is here, what is obtained is the property of the parent scope '</div>', replace:true, transclude: true, restrict:'C', scope:{ title:"@zippyTitle"//Bind the zippy-title attribute on the directive element}, link:function(scope,element,attrs) { var title = angular.element(element.children()[0]), opened = false; title.bind("click", toogle); element.addClass("closed"); function toogle() { opened = !opened; element.removeClass(opened ? "closed" : "opened"); element.addClass(opened ? "opened" : "closed"); } } }; }); </script></body></html>