Unter den Diensten von Angular gibt es einige Dienste, die Sie verstehen müssen, da sie als Kern von ng bezeichnet werden können. Heute möchte ich die beiden Kerndienste von ng, $parse und $compile, vorstellen. Tatsächlich reden viele Leute über diese beiden Dienste, aber auf 100 Leser kommen 100 Hamlets. Ich bin hier, um über mein Verständnis dieser beiden Dienste zu sprechen.
Sie fragen sich vielleicht, dass $eval eigentlich kein Dienst ist und nicht als Dienst angesehen werden kann. Darüber hinaus basiert es auch auf der Analyse und kann daher nur als ein anderer betrachtet werden Version von $parse. Werfen wir einen Blick auf die Definition von $eval im ng-Quellcode
$eval: function(expr, locals) { return $parse(expr)(this, locals); },
I Ich glaube, jeder wird es verstehen, nachdem er den Quellcode gelesen hat. Okay, beginnen wir jetzt mit der Erklärung der beiden Kerndienste. Wenn Sie das Gefühl haben, dass das, was ich gesagt habe, falsch ist, können Sie es gerne im Kommentarbereich oder im privaten Chat darauf hinweisen. um anderen Lesern keinen Schaden zuzufügen.
Wenn ich über diese beiden Dienste spreche, möchte ich in diesem Beitrag zunächst auf ein Konzept eingehen: Kontext
Ich glaube, dass viele Menschen von diesem „Kontext“ gehört haben, aber vielleicht ist es so etwas vage, lass es mich dir erklären und sehen, ob du diese Aussage akzeptierst.
Erinnern Sie sich an die Datenbindung von Angular? Zum Beispiel: Ich habe jetzt einen Controller namens TestCtrl und sein Inhalt ist wie folgt:
.controller('TestCtrl', function($scope) { $scope.test = "Boo!!!" })
Und in HTML sieht unser Code so aus
<body ng-controller="TestCtrl"> {{test}} </body>
Dann kennt jeder das Ergebnis, ohne darüber nachzudenken, das Wort Boo!!! wird auf jeden Fall auf der Seite angezeigt.
Aber was ist, wenn ich die ng-controller-Direktive lösche? Das heißt, ich habe den Controller nicht in HTML deklariert. Was passiert, wenn Sie {{test}} direkt binden?
Es gibt nur ein Ergebnis, das heißt, es gibt nichts auf der Seite (ps: weil Sie ng-app deklariert haben). Verstehst du das?
Der Controller entspricht einem Kontextcontainer. Der tatsächliche Kontext ist tatsächlich $scope. Wenn die Seite an den Test gebunden ist, ist der aktuelle Kontext der $scope im Controller wird danach suchen. Überprüfen Sie, ob der Kontext $scope Ihres Controllers einen Test hat. Wenn ja, wird er natürlich angezeigt, aber was ist, wenn Sie den Controller nicht deklarieren? Sein Kontextcontainer ist ng-app, dann ist sein tatsächlicher Kontext $rootScope. Zu diesem Zeitpunkt sucht er nach $rootScope, um zu sehen, ob es einen Test gibt.
Okay, wir haben mit dem Konzept des Kontexts fertig. Es ist eigentlich ganz einfach zu verstehen.
Kommen wir also zur Sache, fangen wir an, über $ zu reden analysieren. Das erste, was wir uns ansehen müssen, ist das ng-API-Dokument
var getter = $parse('user.name'); var setter = getter.assign; var context = {user:{name:'angular'}}; var locals = {user:{name:'local'}}; expect(getter(context)).toEqual('angular'); setter(context, 'newValue'); expect(context.user.name).toEqual('newValue'); expect(getter(context, locals)).toEqual('local');
Was Sie sehen, sind die kostengünstigsten Codezeilen im ng Dokument für den $parse-Dienst,
Getter und Setter sind die bekannten Get-Methoden und Set-Kontexte und Locals sind nur JSON-Objekte. Der Zweck besteht darin, die Kontextbeziehung zu simulieren.
Die Die folgenden vier Anweisungen können den Test schließlich bestehen. Jetzt analysieren wir sie einzeln. Vor der Analyse muss ich erklären, was $parse
$parse service eigentlich eine Funktion zum Parsen von Ausdrücken ist wie ng-model="test", schreiben Sie dies in HTML. Wer weiß, dass Sie in Ihrem ng-model="test" tatsächlich den Wert in test im Bereich (Kontext) des aktuellen Controllers (Kontext) binden möchten ng hilft Ihnen, dies über den $parse-Dienst zu analysieren. Wenn Sie also den $parse-Dienst aufrufen, müssen Sie das Kontextobjekt übergeben, um ng mitzuteilen, wo der Bereich (Kontext) Ihren Test finden wird.
Wir sehen also, dass die erste Zeile des Testcodes so aussieht:
getter(context)).toEqual('angular') //实际上就是 $parse('user.name')(context)
In diesem Kontext ist es der Kontext und Es kann „eckig“ zurückgeben. Das Prinzip dieser Zeichenfolge besteht darin, diese drei Schritte zu durchlaufen:
1 Holen Sie sich den aktuellen Ausdruck user.name
2. {name:'angular'}}
3. Suchen Sie den Ausdruck in den oberen und unteren Frageobjekten und rufen Sie schließlich das Zeichen „angular“ ab, um
zu erstellen, damit dieser Testcode erfolgreich ist .
Sehen wir uns die zweite Methode an, die Setter-Methode
setter(context, 'newValue');//实际上就是 $parse('user.name').assign(context, 'newValue') expect(context.user.name).toEqual('newValue');//测试数据上下文的值是否被改变
Die Setter-Methode hier ist eigentlich eine Änderungswertmethode
1. Holen Sie sich den aktuellen Ausdruck user.name
2. Holen Sie sich das aktuelle Kontextobjekt {user:{name:'angular'}}
3. Ändern Sie den Wert im Ausdruck , Kontextobjektprogrammierung {user:{name:'newValue'}}
Also hat sich das Kontextobjekt geändert, wenn die Getter-Methode erneut zum Abrufen des Ausdrucks verwendet wird. Der Kontext hat sich von {user:{name:) geändert. 'angular' }} --> {user:{name:'newValue'}}, der Wert des letztendlich erhaltenen Ausdrucks ist natürlich "newValue", daher besteht der Testcode auch.
expect(getter(context, locals)).toEqual('local');//实际上就是$parse('user.name')(context, locals)
Was hier gezeigt wird, ist eigentlich die Kontextersetzungsfunktion.
In der Getter-Methode können wir nicht nur den ersten Kontext auswählen, sondern wenn wir den zweiten Parameter übergeben, wird der erste Kontext durch den zweiten Kontext überschrieben.
1. Holen Sie sich den aktuellen Ausdruck user.name
2. Holen Sie sich das aktuelle Kontextobjekt {user:{name:'angular'}}
3. name:'local'}}
4. Ermitteln Sie den Wert des Ausdrucks nach dem Parsen
Zurück zu $eval: Aus dem Quellcode von $eval können wir ersehen, dass $eval nur eine Get-Funktion und keine Set-Funktion hat. Manchmal können wir jedoch einen zweiten Kontext übergeben, um den Effekt einer Wertänderung zu erzielen.
Der $parse-Dienst wurde hier abgeschlossen und der nächste Schritt ist $compile
------------------------------------ - --------------------------
Wenn Sie das Konzept von $parse verstehen, denke ich, dass $compile ähnlich ist Verstehen Sie, es ist tatsächlich $parse sehr ähnlich. Es analysiert jedoch einen Teil des HTML-Codes und seine Funktion besteht darin, eine tote Vorlage in eine Live-Vorlage umzuwandeln, was auch der Kerndienst des Befehls ist.
Wenn Sie beispielsweise einen HTML-Code
$compile('dead template') (Kontextobjekt), sodass die tote Vorlage in die Live-Vorlage programmiert wird und Sie Vorgänge an diesem Live-HTML-Code ausführen können, z. B. das Hinzufügen zum aktuellen Knoten usw. warten.
Aber in der Anweisung gibt sie zwei Funktionen zurück: Pre-Link und Post-Link
Die erste ausgeführte Funktion ist Pre-Link, und die Durchlaufreihenfolge für dieselbe Anweisung stammt von Traversal from Zu diesem Zeitpunkt hat sich der DOM-Knoten noch nicht stabilisiert und kann einige Bindungsereignisoperationen nicht ausführen, aber wir können hier einige Initialisierungsdaten verarbeiten.
Die zweite Ausführung ist die Post-Link-Funktion, die wir oft als Link-Funktion bezeichnen. In diesem Stadium hat sich der DOM-Knoten normalerweise stabilisiert geht hier weiter.