"Wie funktioniert this
und $scope
funktioniert in AngularJS-Controllern?"
Kurze Antwort :
this
- Wenn die Controller-Konstruktorfunktion aufgerufen wird,
this
ist dies der Controller.
- Wenn eine für ein
$scope
Objekt definierte Funktion aufgerufen wird, this
ist der "Gültigkeitsbereich gültig, als die Funktion aufgerufen wurde". Dies kann (oder auch nicht!) Sein, auf dem $scope
die Funktion definiert ist. Also, innerhalb der Funktion this
und $scope
möglicherweise nicht gleich.
$scope
- Jeder Steuerung ist ein
$scope
Objekt zugeordnet.
- Eine Controller- (Konstruktor-) Funktion ist dafür verantwortlich, Modelleigenschaften und -funktionen / -verhalten für die zugehörigen Funktionen festzulegen
$scope
.
- Über
$scope
HTML / view kann nur auf Methoden zugegriffen werden, die für dieses Objekt definiert sind (und übergeordnete Bereichsobjekte, wenn die prototypische Vererbung im Spiel ist). ZB von ng-click
, Filtern usw.
Lange Antwort :
Eine Controller-Funktion ist eine JavaScript-Konstruktorfunktion. Wenn die Konstruktorfunktion ausgeführt wird (z. B. wenn eine Ansicht geladen wird), this
(dh der "Funktionskontext"), wird das Controller-Objekt festgelegt. Also in der Controller-Konstruktorfunktion "tabs", wenn die addPane-Funktion erstellt wird
this.addPane = function(pane) { ... }
Es wird auf dem Controller-Objekt erstellt, nicht auf $ scope. Ansichten können die Funktion addPane nicht sehen - sie haben nur Zugriff auf Funktionen, die in $ scope definiert sind. Mit anderen Worten, im HTML funktioniert dies nicht:
<a ng-click="addPane(newPane)">won't work</a>
Nachdem die Controller-Konstruktorfunktion "tabs" ausgeführt wurde, haben wir Folgendes:
Die gestrichelte schwarze Linie zeigt die prototypische Vererbung an - ein isolierter Bereich erbt prototypisch von Scope . (Es erbt nicht prototypisch von dem Gültigkeitsbereich, in dem die Direktive im HTML gefunden wurde.)
Jetzt möchte die Link-Funktion der Pane-Direktive mit der Tabs-Direktive kommunizieren (was wirklich bedeutet, dass sie die Tabs in irgendeiner Weise beeinflussen muss, um den Bereich zu isolieren). Ereignisse könnten verwendet werden, aber ein anderer Mechanismus besteht darin, dass die Fensteranweisung require
den Registerkarten-Controller enthält. (Es scheint keinen Mechanismus für die Fensteranweisung zu require
den Registerkarten $ scope zu geben.)
Dies wirft also die Frage auf: Wenn wir nur Zugriff auf den Tabs-Controller haben, wie erhalten wir Zugriff auf die Tabs, die $ scope isolieren (was wir wirklich wollen)?
Nun, die rot gepunktete Linie ist die Antwort. Der "Bereich" der Funktion addPane () (ich beziehe mich hier auf den Funktionsumfang / die Schließungen von JavaScript) ermöglicht der Funktion den Zugriff auf die Registerkarten, die $ scope isolieren. Dh addPane () hat Zugriff auf die "Registerkarten IsolateScope" im obigen Diagramm aufgrund eines Abschlusses, der beim Definieren von addPane () erstellt wurde. (Wenn wir stattdessen addPane () für das tabs $ scope-Objekt definieren würden, hätte die pane-Direktive keinen Zugriff auf diese Funktion und hätte daher keine Möglichkeit, mit den tabs $ scope zu kommunizieren.)
Zur Beantwortung des anderen Teils Ihrer Frage: how does $scope work in controllers?
:
In Funktionen, die für $ scope definiert sind, this
wird "der Gültigkeitsbereich von $ festgelegt, in dem / wann die Funktion aufgerufen wurde". Angenommen, wir haben den folgenden HTML-Code:
<div ng-controller="ParentCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - parent scope
<div ng-controller="ChildCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - child scope
</div>
</div>
Und das hat ParentCtrl
(allein)
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
Wenn Sie auf den ersten Link klicken, wird dies angezeigt this
und $scope
ist identisch, da " der Gültigkeitsbereich, der beim Aufruf der Funktion gültig war " der mit dem verknüpfte Gültigkeitsbereich ist ParentCtrl
.
Den zweiten Link klicken , wird verraten this
und $scope
sind nicht gleich, da „ der Umfang in Kraft , wenn die Funktion aufgerufen wurde “ ist der Umfang im Zusammenhang mit der ChildCtrl
. Also hier this
ist auf ChildCtrl
's gesetzt $scope
. Innerhalb der Methode $scope
befindet sich immer noch der Bereich ParentCtrl
$.
Geige
Ich versuche, nicht this
innerhalb einer in $ scope definierten Funktion zu verwenden, da es verwirrend wird, welcher $ scope betroffen ist, insbesondere wenn man bedenkt, dass ng-repeat, ng-include, ng-switch und Direktiven alle ihre eigenen untergeordneten Bereiche erstellen können.