„Jak działa thisi $scopedziała w kontrolerach AngularJS?”
Krótka odpowiedź :
this
- Gdy wywoływana jest funkcja konstruktora kontrolera,
thisto kontroler.
- Gdy
$scopewywoływana thisjest funkcja zdefiniowana w obiekcie, „zasięg obowiązuje, gdy funkcja została wywołana”. Może to być (lub nie!) $scopeFunkcja zdefiniowana na tej funkcji. Więc wewnątrz funkcji thisi $scopemoże nie być taka sama.
$scope
- Każdy kontroler ma powiązany
$scopeobiekt.
- Funkcja kontrolera (konstruktora) jest odpowiedzialna za ustawianie właściwości modelu i funkcji / zachowania na powiązanej z nim funkcji
$scope.
- Tylko metody zdefiniowane na tym
$scopeobiekcie (i obiektach nadrzędnych, jeśli w grę wchodzi dziedziczenie prototypowe) są dostępne z widoku HTML /. Np. Z ng-clickfiltrów, itp.
Długa odpowiedź :
Funkcja kontrolera to funkcja konstruktora JavaScript. Gdy funkcja konstruktora jest wykonywana (np. Gdy ładuje się widok), this(tzn. „Kontekst funkcji”) jest ustawiany na obiekt kontrolera. Tak więc w funkcji konstruktora kontrolera „tabs”, gdy tworzona jest funkcja addPane
this.addPane = function(pane) { ... }
jest tworzony na obiekcie kontrolera, a nie na $ scope. Widoki nie widzą funkcji addPane - mają dostęp tylko do funkcji zdefiniowanych w $ scope. Innymi słowy, w HTML to nie zadziała:
<a ng-click="addPane(newPane)">won't work</a>
Po wykonaniu funkcji konstruktora kontrolera „tabs” otrzymujemy:

Przerywana czarna linia wskazuje na dziedzictwo prototypowe - zakres izolowany prototypowo dziedziczy po Scope . (Nie dziedziczy prototypowo z zakresu obowiązującego w przypadku napotkania dyrektywy w HTML).
Teraz funkcja linkowania dyrektywy panelu chce komunikować się z dyrektywą tabs (co tak naprawdę oznacza, że musi wpływać na tabs w jakiś sposób izolować $ scope). Zdarzenia mogą być użyte, ale innym mechanizmem jest ustawienie dyrektywy requiretabulatora na kontroler kart. (Wygląda na to, że nie ma mechanizmu dyrektywy panelu requirew zakresie $ tabs.)
Nasuwa się więc pytanie: jeśli mamy dostęp tylko do kontrolera kart, w jaki sposób uzyskujemy dostęp do kart izolujących $ scope (czego naprawdę chcemy)?
Cóż, czerwona kropkowana linia jest odpowiedzią. „Zasięg” funkcji addPane () (odnoszę się tutaj do zakresu / zamknięć funkcji JavaScript) daje tej funkcji dostęp do zakładek izolujących $ scope. Tj. AddPane () ma dostęp do „zakładek IsolateScope” na powyższym diagramie z powodu zamknięcia, które zostało utworzone, gdy zdefiniowano addPane (). (Jeśli zamiast tego zdefiniowaliśmy addPane () na obiekcie tabs $ scope, dyrektywa pane nie miałaby dostępu do tej funkcji, a zatem nie miałaby możliwości komunikowania się z tabs $ scope.)
Aby odpowiedzieć na drugą część pytania how does $scope work in controllers?:
W ramach funkcji zdefiniowanych w $ scope, thisustawiono na „zakres $, który obowiązuje gdzie / kiedy funkcja została wywołana”. Załóżmy, że mamy następujący kod HTML:
<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>
I ParentCtrl(wyłącznie) ma
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
Kliknięcie pierwszego linku pokaże to thisi $scopejest takie samo, ponieważ „ zakres obowiązujący w momencie wywołania funkcji ” to zakres powiązany z ParentCtrl.
Kliknięcie drugiego linku ujawni this i $scopeto nie to samo, gdyż „ zakres w efekcie, gdy funkcja została wywołana ” jest zakres związany z ChildCtrl. Więc tutaj thisjest ustawiony na ChildCtrl„s $scope. Wewnątrz metody $scopenadal ParentCtrlznajduje się zakres $.
Skrzypce
Staram się nie używać thiswewnątrz funkcji zdefiniowanej w $ scope, ponieważ staje się mylące, którego $ zakres ma wpływ, szczególnie biorąc pod uwagę, że wszystkie powtórzenia, włączanie, przełączanie i przełączanie mogą tworzyć własne zakresy potomne.