Zakres jest wiązaniem utworzonym pomiędzy widokiem HTML i przynależącym do tego widoku kodem Javascript.
Wiązanie to opisane jest przez obiekt, do którego mamy dostęp po obu stronach tej relacji.
Możemy więc zmieniać zawartość tego obiektu zarówno z poziomu HTML-a jak i z poziomu kodu Javascript.
Zmiany wykonane po jednej stronie są automatycznie widoczne po stronie drugiej.
Zasadnicza różnica pomiędzy kodem HTML a Javascript polega na tym, że w Javascript odwołujemy się do własności
poprzez użycie
konwencji obiektowej, natomiast w HTML używamy bezpośrednio
nazwy własności.
Javascript:
HTML:
Zakres główny i zakresy podrzędne
Z pojęciem scope silnie związane jest pojęcie
root scope, które oznacza główny zakres aplikacji.
Każda aplikacja może mieć tylko i wyłącznie jeden root scope. Ten natomiast może mieć dowolną ilość zakresów podrzędnych.
Tych może być całkiem sporo, ponieważ każdorazowe użycie dyrektywy
ng-controller oraz
ng-repeat
doprowadza do stworzenia nowego zakresu. W przypadku zagnieżdżania komponentów, każdy nowy zakres
staje się automatycznie podrzędny do zakresu komponentu położonego wyżej:
W powyższym listingu możemy zaobserwować cztery różne kontrolery:
AppCtrl - kontroler, dla którego stworzony jest zakres główny (
root scope)
ParentCtrl - kontroler, dla którego stworzony jest zakres podrzędny (scope)
FirstChildCtrl - kontroler, dla którego stworzony jest kolejny (nowy) zakres podrzędny (scope)
SecondChildCtrl - kontroler, dla którego stworzony jest jeszcze kolejny (kolejny nowy) zakres podrzędny (scope)
Istotne jest, że scope'y mogą dziedziczyć własności ze scope swojego rodzica, ale tak się dzieje tylko w przypadku
zakresów o typie dziecka ("child scopes"). Istnieją bowiem jeszcze zakresy wyizolowane ("isolated scopes") i one nie potrafią dziedziczyć własności.
Ten typ występuje w ramach dyrektyw, od których oczekujemy tego żeby były odseparowane od zakresu swojego rodzica.
Więcej na ten temat piszemy w rozdziale:
Dyrektywy własne,
w paragrafie "Zakres dyrektyw".
Kontrolery a ich zakresy
Wracając do tematu relacji nawiązywanej między kontrolerem a zakresem, trzeba wspomnieć jeszcze o tym jaka jest ich interakcja:
- Kontroler może poprzez zmianę scope'a wpływać na zmianę wartości modelu.
Javascript:
HTML:
- Kontroler wykorzystuje scope do tego by wyeksponować swoje funkcje, dzięki czemu stają się one widzialne dla widoku (w HTML), który w konsekwencji tego może je uruchomić.
Javascript:
HTML:
- Kontroler może rejestrować elementy obserwujące (watches) zmiany w modelu, które są uruchamiane automatycznie po każdej jego zmianie.
Javascript:
HTML:
W zasadzie to tyle z tematów, które chcieliśmy poruszyć w tym rozdziale. Jeśli interesuje Was więcej detali to
zapraszamy do sekcji linków na dole strony. Załączyliśmy tam odnośnik do oryginalnej dokumentacji AngularJS, do paragrafu
opisującego zakresy.
Rekomendacja
Naprawdę bardzo mocno polecamy pobranie darmowego projektu dostępnego na naszym blogu pod linkiem
Projekt startowy Spring Boot + AngularJS.
Będzie on doskonałym uzupełnieniem wiedzy zdobytej w tym paragrafie.
Korzystając ze scopów należy pamiętać, aby unikać nadmiernego używania własności scopów nadrzędnych z poziomu scopów podrzędnych, gdyż może
to z czasem doprowadzić do zmniejszenia czytelności kodu oraz powodować nieoczekiwane zachowanie komponentów po ich ewentualnej zmianie w przyszłości.
Starajmy się zawsze trzymać nasze zmiany w obrębie zakresu dedykowanego kontrolerowi, w którym sie znajdujemy.
Mimo, że w kontrolerach mamy bezpośredni dostęp do zakresu głównego (poprzez wstrzyknięcie obiektu
$rootScope),
to tutaj również starajmy się korzystać z tego z umiarem. Zdecydowana większość funkcjonalności związanych
bezpośrednio z danym komponentem powinna być obsługiwana w ramach jego scope'a.
Regularne ustawianie różnych własności z różnych kontrolerów z czasem doprowadzi do niezłego bałaganu w kodzie, który trudno będzie posprzątać.
W takiej sytuacji po prostu nie wiadomo skąd i dlaczego dana wartość nagle uległa zmianie.
Używamy w StartAPPa
Oczywiście wszędzie w aplikacji korzystamy z zakresów. Niemniej fragmenty kodu, które posłużyły nam w tym rozdziale za przykład (oparte o komponentem daty) pochodzą
konkretnie z modułu
Formularz Zaawansowany.
W pełnej wersji kod przedstawionych przykładów jest dużo bardziej rozbudowany i zawiera dodatkowo obsługę pozostałych komponentów.
Mowa tutaj o komponentach typu
select,
checkbox,
radio i wielu innych,
których działanie możecie zobserwować po zalogowaniu się do aplikacji StartAPPa i wybraniu sekcji Formularz Zaawansowany.
Linki:
https://docs.angularjs.org/guide/scope