Kontroler  (Controller)

Typowa aplikacja webowa posiada widok wykonany w HTML oraz mechanizm przetwarzania danych i obsługi zdarzeń realizowany przez Javascript. W przypadku AngularJS funkcjonuje to dokładnie tak samo, jednak framework ten wprowadza w tej materii dodatkowe udogodnienia. W rozdziałach Moduł (Module) oraz Zakres (Scope) szeroko omawialiśmy podział na komponenty oraz zakresy ich działania, stąd wiemy już, że każdy wydzielony przez nas fragment HTML może posiadać swój własny, dedykowany "kawałek" przestrzeni Javascript, który obsługuje jego zachowanie. Ten przysłowiowy "kawałek" to kontroler i właśnie o tym będziemy pisać w tym rozdziale.

Tworzenie kontrolerów

Przypomnijmy, że w rozdziale poświęconym zakresom pisaliśmy między innymi o tym, że HTML jest wiązany z odpowiadającym mu kodem Javascript za pomocą obiektu $scope. Precyzując, wiązany jest z bytem AngularJS, który powstaje poprzez użycie funkcji konstruującej i który nazywany jest właśnie kontrolerem:
angular.module(<NAZWA_MODUŁU>).controller(
<NAZWA_KONTROLERA>, [<WSTRZYKIWANE_ZALEŻNOŚCI>, function(<WSTRZYKIWANE_ZALEŻNOŚCI>) {...}])
Przykład:
angular.module('appa.form').controller(
      'AppaFormCtrl', [ '$scope', 'growl', 'AppaFormFactory', ..., function($scope, growl, AppaFormFactory, ...) {

    ...
    
    AppaFormFactory.createOrUpdateAppaItem(appaItem, $scope.appa.imageFile).then(function(response) {

        ...
        growl.success("Item saved successfully");

    }, function(response) {

        ...
        growl.error("Saving item failed", {
            ttl : 10000
        });

    });    
        
} ]);
Widzimy, że kontroler podpinamy do modułu podając nazwę kontrolera oraz funkcję konstruującą. Funkcja ta zawiera kilka wstrzykniętych zależności, a wśród nich wspomniany $scope. Pozostałe dwie zależności podane są poprzez bezpośrednie użycie nazwy bez dodatkowego prefixu $ i reprezentują przykładowe usługi jakie możemy wstrzyknąć do kontrolera. Tak więc poza scopem, którego prefix $ oznacza, że jest on elementem wbudownanym w Angulara, mamy tutaj jeszcze:

growl - fabrykę pochodzącą z zewnętrznej biblioteki
AppaFormFactory - fabrykę stworzoną przez nas w celu przetwarzania danych

Przywykliśmy do tego, że nasze własne fabryki nazywamy stosując dużą literę na początku nazwy, co jednak nie jest ogólną zasadą, a jedynie przyjmowaną przez nas konwencją. Istotne jest natomiast aby nie rozpoczynać nazwy od prefixu z dolarem, gdyż może to doprowadzić do kolizji z nazwami stosowanymi przez core AngularJS.

Oczywiście lista określonych typów, które możemy wstrzykiwać (injectable types) nie ogranicza się tylko do fabryk i wygląda tak:
  • Wartość (Value)
  • Fabryka (Factory)
  • Serwis (Service)
  • Dostawca (Provider)
Daje nam to dosyć szerokie pole manewru i umożliwia skuteczne rozdzielenie logiki związanej bezpośrednio z naszym komponentem HTML (kontroler), od części zajmującej się wymianą i przetwarzaniem danych (fabryki, serwisy).

Wiązanie kontrolera z HTML-em

Po stworzeniu kodu Javascript kontrolera, musimy teraz zdecydować z jakim widokiem HTML chcemy go związać. Możemy to wykonać na kilka sposobów:
  • Dyrektywa ng-controller - parametr przekazany do dyrektywy to nazwa naszego kontrolera:
    <div ng-controller="AppaFormCtrl">
    ...
    </div>
    
  • Własność controller - własność obiektu konfigurującego stan w ramach routingu (więcej o tym temacie piszemy w rozdziale Dostawca stanu i dyrektywa ui-view):
    $stateProvider.state('appaForm', {
        ...
        controller : 'AppaFormCtrl'
    })
    
  • Własność controller - własność obiektu konfigurującego dyrektywę (o dyrektywach piszemy w kilku innych rozdziałach kursu, m.in. w Dyrektywy własne):
    angular.module('appa.form').directive('appaForm', function() {
    
        return {
            ...
            controller : 'AppaFormCtrl'
        };
    })
    
Rekomendacja
Starajmy się nie tworzyć zbyt dużych i ciężkich kontrolerów. AngularJS cechuje modułowość i dlatego też budując kod aplikacji miejmy to na uwadze. Warto wydzielać niezależne funkcjonalnie fragmenty HTML i dedykować im osobne kontrolery. Otrzymujemy wtedy czytelny i łatwy w utrzymaniu kod, co znacznie uprości jego rozwój w przyszłości.

Framework dostarcza nam również szereg możliwości do tego, aby dzielić kod zgodnie z jego przeznaczeniem. Tak więc kontrolery powinny nam służyć głównie do finalnej inicjalizacji komponentów oraz obsługi zdarzeń. Algorytmy przetwarzające logikę biznesową, jak również odwołania do zewnętrznych usług powinny trafiać do fabryk lub serwisów, które wystawią kontrolerowi metody do uruchomienia (tak jak w przykładzie wyżej AppaFormFactory udostępnia metodę createOrUpdateAppaItem). Jeśli natomiast potrzebujemy wykonać filtrowanie danych w ramach komponentów HTML, to w tym celu możemy również skorzystać z mechanizmu filtrów (o czym będziemy pisać już niedługo w osobnym rozdziale).
Używamy w StartAPPa


Kontrolery są podstawowym elementem frameworka AngularJS więc oczywiście spotkacie je w każdym "kącie" aplikacji. Jeśli bardzo interesuje Was podział na kontrolery w połączeniu z dyrektywami polecamy szczególnie pobranie modułu Formularz Zaawansowany. Zawiera on wiele różnych komponentów HTML, które są wydzielone do osobnych dyrektyw z dedykowanymi kontrolerami.
Linki:
https://docs.angularjs.org/guide/controller

Stale się rozwijamy, a więc bądź na bieżąco!
Na ten adres będziemy przesyłać informacje o ważniejszych aktualizacjach, a także o nowych materiałach pojawiających się na stronie.
Polub nas na Facebooku:
Nasi partnerzy: stackshare
Javappa to również profesjonalne usługi programistyczne oparte o technologie JAVA. Jeśli chesz nawiązać z nami kontakt w celu uzyskania doradztwa bądź stworzenia aplikacji webowej powinieneś poznać nasze doświadczenia.
Kliknij O nas .


Pozycjonowanie stron: Grupa TENSE