AngularJS #2 – ng-controller

AngularJS



Muszę przyznać, że AngularJS uczę się dopiero od dwóch miesięcy. Do tej pory używałem jedynie czystego JavaScript i jQuery. Używałem to dobre określenie, bo daleko mi do prawdziwego web dewelopera. Projekt, w którym mam szczęście uczestniczyć łączy Javowy backend z single app, która pisana jest właśnie w AngularJS. Stąd powstał pomysł na niniejszy “kurs” (to za dużo powiedziane). Dla Was (mam nadzieję) będzie to szansa na poznanie AngularJS, a dla mnie możliwość by nauczyć się go lepiej. Nic tak nie pomaga przyswajać wiedzy jak uczenie innych.

Przyznam się bez bicia, że rozkład jazdy konstruuję na bazie materiałów w sieci (polecam: http://egghead.io/). Poza dzieleniem się własnymi doświadczeniami, mam zamiar przemycać co nieco od dużo bardziej doświadczonych deweloperów, a czasami i samych twórców AngularJS.

Przeczytałem gdzieś, że “AngularJS, to w końcu JavaScript bez bólu”. Dwa miesiące wystarczyły mi by się o tym przekonać i mam nadzieję, że uda mi się Wam to pokazać.

ng-controller

Przepraszam za przydługi wstęp. Przechodzę czym prędzej do tematu dzisiejszego wpisu. W poprzednim była już mowa o $scope i pierwszy kontroler AngularJS.

Tworzenie widoku bez separacji HTML, CSS i JavaScript byłoby trudne. Wykorzystanie jedynie podstawowych elementów AngularJS także nie dawałoby nam wiele. Wplecenie w to wszystko własnej logiki biznesowej oraz dodatkowych funkcjonalności byłoby praktycznie niewykonalne bez kontrolerów, które pozwalają tworzyć odpowiednie warstwy ($scope) do zarządzania naszym widokiem.

Z pomocą przychodzi nam dyrektywa (o tym później) ngController, którą udostępnia nam sam AngularJS, a która to odpowiedzialna jest za budowę warstwy MVC (Model – View – Controller). W oficjalnej dokumentacji czytamy:

The ngController directive attaches a controller class to the view. This is a key aspect of how angular supports the principles behind the Model-View-Controller design pattern.

MVC components in angular:
– Model — The Model is scope properties; scopes are attached to the DOM where scope properties are accessed through bindings.
– View — The template (HTML with data bindings) that is rendered into the View.
– Controller — The ngController directive specifies a Controller class; the class contains business logic behind the application to decorate the scope with functions and values.

Jeżeli czytacie o AngularJS, to z pewnością wiecie też czym jest MVC i nie wymaga to większego komentarza.

Twórcy piszą także o aspekcie wykorzystania kontrolerów w routingu ($route – o tym także będzie potem) i ostrzegają przed często popełnianym błędem, w którym to po zdefiniowaniu kontrolera w naszym configu $route nie ma już potrzeby definiowania kontrolera po stronie HTML w postaci dyrektywy ng-controller. Jeżeli ktoś popełni ową gafę, to jego kontroler zostanie wstrzyknięty dwukrotnie, co na pewno nie jest pożądane.

$scope

Jak większość (wszystkie?) dyrektyw w AngularJS, również ngController tworzy swój własny $scope, czyli przestrzeń, w której widoczne są wszystkie zmienne oraz metody zdefiniowane w kontrolerze, który podany został jako argument dyrektywy. Jest to kolejna warstwa naszej aplikacji. Definiując przykładowo nasz kontroler dla atrybutu <div> w HTML, $scope utworzony zostanie dla wszystkich elementów znajdujących się pomiędzy <div> … </div>. Tym samym wszystkie kontrolery utworzone wewnątrz tej struktury “widzieć” będą metody oraz zmienne utworzone w $scope nadrzędnego kontrolera. W drugą stronę to już tak nie działa. Kontroler nadrzędny nie będzie miał dostępu do logiki utworzonej w swoim kontrolerze-dziecku. Możemy sobie wyobrazić dziedziczenie w statycznie typowanych językach, jednak to nie to samo.

Przykłady

Świetnie oddane zostały przykłady tworzenia prostego kontrolera na oficjalnej stronie dyrektywy: ngController. Nie zrobiłbym tego lepiej, dlatego odsyłam Was właśnie tam (co będę pewnie robił częściej, bo dokumentacja jest naprawdę dobra i ciągle się rozwija / rozrasta). Jeżeli komuś mało, to jest kolejna lekcja poświęcona temu tematowi na http://egghead.io/:

[youtube_sc url=”https://www.youtube.com/watch?v=MEmC0QH8ATQ”]