"Wie funktioniert thisund $scopefunktioniert in AngularJS-Controllern?"
Kurze Antwort :
this
- Wenn die Controller-Konstruktorfunktion aufgerufen wird,
thisist dies der Controller.
- Wenn eine für ein
$scopeObjekt definierte Funktion aufgerufen wird, thisist der "Gültigkeitsbereich gültig, als die Funktion aufgerufen wurde". Dies kann (oder auch nicht!) Sein, auf dem $scopedie Funktion definiert ist. Also, innerhalb der Funktion thisund $scopemöglicherweise nicht gleich.
$scope
- Jeder Steuerung ist ein
$scopeObjekt zugeordnet.
- Eine Controller- (Konstruktor-) Funktion ist dafür verantwortlich, Modelleigenschaften und -funktionen / -verhalten für die zugehörigen Funktionen festzulegen
$scope.
- Über
$scopeHTML / 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 requireden Registerkarten-Controller enthält. (Es scheint keinen Mechanismus für die Fensteranweisung zu requireden 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, thiswird "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 thisund $scopeist 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 thisund $scopesind nicht gleich, da „ der Umfang in Kraft , wenn die Funktion aufgerufen wurde “ ist der Umfang im Zusammenhang mit der ChildCtrl. Also hier thisist auf ChildCtrl's gesetzt $scope. Innerhalb der Methode $scopebefindet sich immer noch der Bereich ParentCtrl$.
Geige
Ich versuche, nicht thisinnerhalb 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.