Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung der Kompilierungs- und Linkfunktionen in AngularJS-Anweisungen_AngularJS

Detaillierte Erläuterung der Kompilierungs- und Linkfunktionen in AngularJS-Anweisungen_AngularJS

WBOY
WBOYOriginal
2016-05-16 16:28:541284Durchsuche

Wenn Benutzer Anweisungen in NG verwenden, ist das Link-Attribut normalerweise die am häufigsten verwendete Link-Funktion. Im folgenden Artikel erfahren Sie mehr über die Verwendung und die Unterschiede zwischen Complie, Pre-Link und Post-Link.

Die Anweisungen in AngularJS sind sehr magisch und ermöglichen die Erstellung sehr semantischer und hochgradig wiederverwendbarer Komponenten. Es kann als Pionier der Webkomponenten verstanden werden.

Es gibt viele Artikel und verwandte Bücher zur Verwendung von Anweisungen im Internet. Im Vergleich dazu gibt es nur wenige Einführungen in den Unterschied zwischen Kompilieren und Verknüpfen, geschweige denn vor Verlinkung und Nachverlinkung.

In den meisten Tutorials heißt es einfach, dass die Kompilierung intern in ng verwendet wird, und es wird empfohlen, nur das Link-Attribut zu verwenden. Dies ist in den meisten Anleitungsbeispielen der Fall

Das ist sehr bedauerlich, denn das richtige Verständnis der Unterschiede zwischen diesen Funktionen wird Ihr Verständnis des internen Arbeitsmechanismus von ng verbessern und Ihnen helfen, bessere benutzerdefinierte Anweisungen zu entwickeln.

Folgen Sie mir also und lesen Sie den folgenden Inhalt Schritt für Schritt, um zu verstehen, was diese Funktionen sind und wann sie verwendet werden sollten

In diesem Artikel wird davon ausgegangen, dass Sie bereits über ein gewisses Verständnis von Anweisungen verfügen. Andernfalls wird dringend empfohlen, diesen Artikel zu lesenAbschnitt des AngularJS-Entwicklerhandbuchs zu Anweisungen

So verarbeiten Sie Anweisungen in NG

Bevor wir mit der Analyse beginnen, schauen wir uns zunächst an, wie Anweisungen in ng verarbeitet werden.

Wenn der Browser eine Seite rendert, liest er im Wesentlichen das HTML-Tag, erstellt dann den Dom-Knoten und sendet ein Ereignis an uns, nachdem der Dom-Baum erstellt wurde

Wenn Sie das Skript-Tag verwenden, um den ng-Anwendungscode auf der Seite zu laden, lauscht ng auf das obige Dom-Vervollständigungsereignis und sucht nach Elementen mit dem ng-app-Attribut.

Wenn ein solches Element gefunden wird, beginnt ng mit der Verarbeitung von dom ab dem Startpunkt dieses Elements. Wenn also ng-app zum HTML-Element hinzugefügt wird, beginnt ng mit der Verarbeitung von dom ab dem HTML-Element.

Von diesem Ausgangspunkt aus beginnt ng mit der rekursiven Suche nach allen Unterelementen, die den in der Anwendung definierten Anweisungsregeln entsprechen

Wie ng Anweisungen handhabt, hängt tatsächlich von den Objektattributen ab, wenn es definiert wird. Sie können eine Kompilierungs- oder Link-Funktion definieren oder Pre-Link- und Post-Link-Funktionen anstelle von Link verwenden.

Was ist also der Unterschied zwischen diesen Funktionen? Warum sollten Sie es verwenden und wann sollten Sie es verwenden?

Mit diesen Fragen folgen Sie mir Schritt für Schritt, um diese Geheimnisse zu beantworten

Ein Stück Code

Um den Unterschied zwischen diesen Funktionen zu erklären, werde ich unten ein einfaches und leicht verständliches Beispiel verwenden

1. Wenn Sie Fragen haben, zögern Sie bitte nicht, unten Ihre Kommentare hinzuzufügen

Sehen Sie sich den folgenden HTML-Tag-Code an

                                                                                                                                                                                     Hallo
                                              
                                                                                 



Dann gibt es noch einen Teil des JS-Codes

Code kopieren

Der Code lautet wie folgt:

var app = angle.module('plunker', []);

    Funktion createDirective(name){
      Rückgabefunktion(){
        zurück {
          einschränken: 'E',
          kompilieren: function(tElem, tAttrs){
            console.log(name ': kompilieren');
            zurück {
              pre: function(scope, iElem, iAttrs){
                console.log(name ': pre link');
              },
              Beitrag: function(scope, iElem, iAttrs){
                console.log(name ': post link');
              }
            }
          }
        }
      }
    }

    app.directive('levelOne', createDirective('levelOne'));
    app.directive('levelTwo', createDirective('levelTwo'));
    app.directive('levelThree', createDirective('levelThree'));

结果非常简单:让ng来处理三个嵌套指令,并且每个指令都有自己的会在控制台里打印一行东西来标识自己.

这个例子能够让我们简单的了解到ng在处理指令时,内部的流程

代码输出

下面是一个在控制台输出结果的截图

如果想自己试一下这个例子的话,请点击dieses plnkr,然后在控制台查看结果.

分析代码

第一个要注意的是这些函数的调用顺序:

复制代码 代码如下:

 // KOMPILIERPHASE
    // levelOne:    Kompilierungsfunktion wird aufgerufen
    // levelTwo:    Kompilierungsfunktion wird aufgerufen
    // levelThree:  Kompilierungsfunktion wird aufgerufen

    // PRE-LINK-PHASE
    // levelOne:    Pre-Link-Funktion wird aufgerufen
    // levelTwo:    Pre-Link-Funktion wird aufgerufen
    // levelThree:  Pre-Link-Funktion wird aufgerufen

    // POST-LINK-PHASE (Beachten Sie die umgekehrte Reihenfolge)
    // levelThree: Post-Link-Funktion wird aufgerufen
    // levelTwo:    Post-Link-Funktion wird aufgerufen
    // levelOne:    Post-Link-Funktion wird aufgerufen

这个例子清晰的显示出了ng在link之前编译所有的指令,然后link要又分为了pre-link与post-link阶段.

Sie können den Pre-Link kompilieren, den Pre-Link erstellen und den Post-Link erstellen.

所以上面已经明确标识出了不同的阶段,但是compile与pre-link有什么区别呢,都是相同的执行顺序,为什么还要分成两个不同的函数呢?

DOM

为了挖的更深一点,让我们简单的修改一下上面的代码,它也会在各个函数里打印参数列表中的element变量

复制代码 代码如下:

var app = angle.module('plunker', []);

    Funktion createDirective(name){
      Rückgabefunktion(){
        zurück {
          einschränken: 'E',
          kompilieren: function(tElem, tAttrs){
            console.log(name ': compile => ' tElem.html());
            zurück {
              pre: function(scope, iElem, iAttrs){
                console.log(name ': pre link => ' iElem.html());
              },
              Beitrag: function(scope, iElem, iAttrs){
                console.log(name ': post link => ' iElem.html());
              }
            }
          }
        }
      }
    }

    app.directive('levelOne', createDirective('levelOne'));
    app.directive('levelTwo', createDirective('levelTwo'));
    app.directive('levelThree', createDirective('levelThree'));

Achten Sie auf die Ausgabe in console.log. Außer der Ausgabe des ursprünglichen HTML-Markups gibt es grundsätzlich keine weitere Änderung.

Dies sollte unser Verständnis für den Kontext dieser Funktionen vertiefen.

Führen Sie den Code erneut aus und sehen Sie nach

Ausgabe

Das Folgende ist ein Screenshot der Konsolenausgabe

Wenn Sie es dennoch selbst ausführen möchten, um den Effekt zu sehen, können Sie auf dieses Plnkr klicken und dann die Ausgabeergebnisse in der Konsole anzeigen.

Beobachten

Das Ergebnis der Ausgabe von Dom kann einige interessante Dinge offenbaren: Der Dom-Inhalt unterscheidet sich in den Kompilierungs- und Pre-Link-Funktionen

Also, was ist passiert?

Kompilieren

Wir wissen bereits, dass ng mit der Verarbeitung des Doms beginnt, wenn es feststellt, dass die Domkonstruktion abgeschlossen ist.

Wenn ng also den Dom durchquert, trifft es auf das Element der ersten Ebene und lernt aus seiner Definition, dass es einige notwendige Funktionen ausführen muss

Da die Kompilierungsfunktion im Befehlsobjekt der Level-1-Direktive definiert ist, wird sie aufgerufen und ein Elementobjekt als Parameter übergeben

Wenn Sie genau hinsehen, werden Sie feststellen, dass es sich beim Erstellen dieses Elementobjekts durch den Browser immer noch um das ursprüngliche HTML-Markup handelt

1. In ng wird normalerweise der ursprüngliche Dom verwendet, um das Vorlagenelement zu identifizieren, daher habe ich beim Definieren der Kompilierungsfunktionsparameter den Namen tElem verwendet.

Sobald die Kompilierungsfunktion in der Direktive „levelone“ ausgeführt wird, durchläuft ng seine DOM-Knoten rekursiv in der Tiefe und wiederholt diese Vorgänge dann auf Ebene zwei und drei.

Post-Link

Bevor wir uns mit der Pre-Link-Funktion befassen, werfen wir einen Blick auf die Post-Link-Funktion.

2. Wenn Sie beim Definieren der Anweisung nur eine Link-Funktion verwenden, behandelt ng diese Funktion als Post-Link, daher müssen wir diese Funktion zuerst besprechen
Nachdem ng das gesamte DOM durchlaufen und alle Kompilierungsfunktionen ausgeführt hat, ruft es die zugehörige Post-Link-Funktion in umgekehrter Reihenfolge auf

Der Dom beginnt nun, die Post-Link-Funktion umzukehren und auszuführen. Daher schien dieser umgekehrte Aufruf vorher etwas seltsam, aber er macht tatsächlich vollkommen Sinn.

Beim Ausführen eines Befehls-Post-Links, der Unterbefehle enthält, kann die umgekehrte Post-Link-Regel sicherstellen, dass der Post-Link seiner Unterbefehle bereits ausgeführt wurde.

Wenn wir also die Post-Link-Funktion der Anweisung der Ebene eins ausführen, können wir sicherstellen, dass die Post-Links der Ebenen zwei und drei tatsächlich ausgeführt wurden.

Aus diesem Grund denken die Leute, dass Post-Link der sicherste oder standardmäßige Ort zum Schreiben von Geschäftslogik ist.

Aber warum unterscheidet sich das Element hier von dem in der Kompilierung?

Sobald ng die Kompilierungsfunktion der Anweisung aufruft, erstellt es ein Elementinstanzobjekt des Vorlagenelements und stellt ihm ein Gültigkeitsbereichsobjekt zur Verfügung. Dieser Bereich kann eine neue Instanz sein oder bereits vorhanden sein ein Unterbereich. Es kann sich auch um einen unabhängigen Bereich handeln, der ganz vom Bereichsattributwert im Anweisungsdefinitionsobjekt abhängt

Wenn also eine Verknüpfung erfolgt, sind dieses Instanzelement und dieses Bereichsobjekt bereits verfügbar und werden von ng als Parameter an die Parameterliste der Post-Link-Funktion übergeben.

1. Ich persönlich verwende immer den iElem-Namen, um die Parameter einer Link-Funktion zu definieren, und er zeigt auf die Elementinstanz

Das Elementparameterobjekt der Post-Link-Funktion (Pre-Link) ist also eine Elementinstanz und kein Vorlagenelement.

Die Ausgabe im obigen Beispiel ist also anders

Vorverlinkung

Beim Schreiben einer Post-Link-Funktion können Sie sicherstellen, dass bei Ausführung der Post-Link-Funktion die Post-Link-Funktionen aller ihrer untergeordneten Anweisungen bereits ausgeführt wurden.

In den meisten Fällen kann es besser sein, daher verwenden wir es normalerweise zum Schreiben von Befehlscodes.

NG stellt uns jedoch einen zusätzlichen Hook-Mechanismus zur Verfügung, nämlich die Pre-Link-Funktion, die sicherstellt, dass ein anderer Code ausgeführt wird, bevor die Post-Link-Funktion aller Unteranweisungen ausgeführt wird.

Dieser Satz ist eine wiederholte Betrachtung wert

Die Pre-Link-Funktion wird garantiert ausgeführt, bevor der Post-Link der Elementinstanz und aller ihrer Unteranweisungen ausgeführt wird.

Daher ist es sinnvoll, die Post-Link-Funktion in umgekehrter Reihenfolge auszuführen, und es handelt sich dabei selbst um die ursprüngliche sequentielle Ausführung der Pre-Link-Funktion

Dies bedeutet auch, dass die Pre-Link-Funktion vor den Pre-Link-Funktionen aller ihrer Unteranweisungen ausgeführt wird. Der vollständige Grund lautet also:

Die Pre-Link-Funktion eines Elements wird garantiert ausgeführt, bevor der Post-Link und der Pre-Link aller seiner Unterbefehle ausgeführt werden. Siehe Abbildung unten:

Rezension

Wenn wir auf die ursprüngliche Ausgabe oben zurückblicken, können wir deutlich erkennen, was passiert ist:


Code kopieren Der Code lautet wie folgt:

    // HIER SIND DIE ELEMENTE NOCH DIE URSPRÜNGLICHEN VORLAGENELEMENTE

    // KOMPILIERPHASE
    // levelOne:    Kompilierungsfunktion wird im Original-DOM aufgerufen
    // levelTwo:    Kompilierungsfunktion wird im ursprünglichen DOM aufgerufen
    // levelThree:  Kompilierungsfunktion wird im ursprünglichen DOM

aufgerufen

    // JETZT WURDEN DIE ELEMENTE INSTANZIERT UND
    // SIND AN EINEN UMFANG GEBUNDEN
    // (z. B. NG-REPEAT hätte mehrere Instanzen)

    // PRE-LINK-PHASE
    // levelOne:    Pre-Link-Funktion wird für Elementinstanz aufgerufen
    // levelTwo:    Pre-Link-Funktion wird für Elementinstanz aufgerufen
    // levelThree:  Pre-Link-Funktion wird für Elementinstanz aufgerufen

    // POST-LINK-PHASE (Beachten Sie die umgekehrte Reihenfolge)
    // levelThree: Post-Link-Funktion wird für Elementinstanz aufgerufen
    // levelTwo:    Post-Link-Funktion wird für Elementinstanz aufgerufen
    // levelOne:    Post-Link-Funktion wird für Elementinstanz aufgerufen

概要

回顾上面的分析我们可以描述一下这些函数的区别以及使用情况:

Kompilieren 函数

使用compile函数可以改变原始的dom(template element),在ng创建原始dom实例以及创建scope实例之前.

可以应用于当需要生成多个element实例,只有一个template. element的情况,ng-repeat就是一个最好的例子,它就在是compil e函数阶段改变原始的dom生成多个原始dom节点,然后每个又生成element实例.因为compile只会运行一次,所以当你需要生成多个element实例的时候是可以提高性能的.

template element以及相关的属性是做为参数传递给compile函数的,不过这时候scope是不能用的:

下面是函数样子:

复制代码 代码如下:

/**
    * Kompilierungsfunktion
    *
    * @param tElem – Vorlagenelement
    * @param tAttrs – Attribute des Vorlagenelements
   */
    function(tElem, tAttrs){

        // ...

    };

Pre-link 函数

使用pre-link函数可以运行一些业务代码在ng执行完compile函数之后,但是在它所有子指令的post-link函数将要执行之前.

scope对象以及element实例将会做为参数传递给pre-link函数:

下面是函数样子:

复制代码 代码如下:

/**
    * Pre-Link-Funktion
    *
    * @param Scope – mit dieser Instanz verknüpfter Bereich
    * @param iElem – Instanzelement
    * @param iAttrs – Attribute des Instanzelements
   */
    function(scope, iElem, iAttrs){

        // ...

    };

Post-Link 函数

使用post-link函数来执行业务逻辑,在这个阶段,它已经知道它所有的子指令已经编译完成并且pre- link以及post-link函数已经执行完成.

这就是被认为是最安全以及默认的编写业务逻辑代码的原因.

scope实例以及element实例做为参数传递给post-link函数:

下面是函数样子:

复制代码 代码如下:

/**
    * Post-Link-Funktion
    *
    * @param Scope – mit dieser Instanz verknüpfter Bereich
    * @param iElem – Instanzelement
    * @param iAttrs – Attribute des Instanzelements
   */
    function(scope, iElem, iAttrs){

        // ...

    };

Zusammenfassung

Jetzt sollten Sie die Unterschiede zwischen den Kompilierungs-, Pre-Link- und Post-Link-Funktionen klar verstehen.

Wenn nicht, und Sie ein ernsthafter NG-Entwickler sind, empfehle ich Ihnen dringend, diesen Artikel noch einmal zu lesen, bis Sie ihn verstanden haben

Es ist sehr wichtig, diese Konzepte zu verstehen, die Ihnen helfen können, zu verstehen, wie die nativen Anweisungen von ng funktionieren, und Ihnen auch dabei helfen können, Ihre eigenen benutzerdefinierten Anweisungen zu optimieren.

Wenn Sie noch Fragen haben, können Sie Ihre Fragen gerne unten in den Kommentaren hinzufügen

Ich werde die beiden anderen Punkte der Richtlinie in Zukunft analysieren:

1. Wie funktioniert die Direktive, die das Transklusionsattribut verwendet?
2. Wie hängen die Controller-Funktionen der Anweisungen zusammen

?

Wenn Sie abschließend etwas Falsches an diesem Artikel finden, senden Sie mir bitte rechtzeitig einen Kommentar

Vielen Dank!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn