„Jak działa this
i $scope
działa w kontrolerach AngularJS?”
Krótka odpowiedź :
this
- Gdy wywoływana jest funkcja konstruktora kontrolera,
this
to kontroler.
- Gdy
$scope
wywoływana this
jest funkcja zdefiniowana w obiekcie, „zasięg obowiązuje, gdy funkcja została wywołana”. Może to być (lub nie!) $scope
Funkcja zdefiniowana na tej funkcji. Więc wewnątrz funkcji this
i $scope
może nie być taka sama.
$scope
- Każdy kontroler ma powiązany
$scope
obiekt.
- 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
$scope
obiekcie (i obiektach nadrzędnych, jeśli w grę wchodzi dziedziczenie prototypowe) są dostępne z widoku HTML /. Np. Z ng-click
filtró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 require
tabulatora na kontroler kart. (Wygląda na to, że nie ma mechanizmu dyrektywy panelu require
w 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, this
ustawiono 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 this
i $scope
jest 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 $scope
to nie to samo, gdyż „ zakres w efekcie, gdy funkcja została wywołana ” jest zakres związany z ChildCtrl
. Więc tutaj this
jest ustawiony na ChildCtrl
„s $scope
. Wewnątrz metody $scope
nadal ParentCtrl
znajduje się zakres $.
Skrzypce
Staram się nie używać this
wewną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.