ModułCzęść NR.4Nasz kontroler “MainController” żyje obecnie wewnątrz globalnej przestrzeni nazwy. To jest raczej złym pomysłem. Kiedy budujesz swoją aplikację z Angular to nie chcesz tego robić.

Jeśli spojrzysz na inne aplikacje zbudowane przy użyciu Angular zauważysz, że żaden z kontrolerów nie jest w globalnej przestrzeni nazw.

Takie zachowanie powinno wystąpić tylko w aplikacji demo. O globalnych zmiennych pisałem tutaj.

Kontrolery powinny żyć wewnątrz modułów. Co oznacza słowo moduł. W JavaScript słowo to oznacza wiele.

Moduł z punktu widzenia Angular jest kontenerem na nasz kod, który napisaliśmy. Kontener ten jest dodatkowym mechanizmem, który pozwala na unikanie globalnej przestrzeni nazw.

Moim zadaniem jest więc stworzyć moduł o określonej nazwie, gdzie będę mógł bezpiecznie przechowywać swoje kontrolery.

Jeśli będę korzystał z czyjeś biblioteki, też opartej na kontrolerach Angular, to mam gwarancje, że moje kontrolery i kontrolery z biblioteki nie będą się ze sobą gryzły.

Dla bardzo rozbudowanej aplikacji mogę mieć modułów więcej niż jeden.

Korzystanie z modułów jest bardzo proste.

var app = angular.module("KursAngular", []);

Tworzymy zmienną, która utworzy moduł. Podajemy w nim jego nazwę oraz tablicę zależnych komponentów, do których moduł będzie się odwoływał. Obecnie podaję tutaj pustą tablicę.

Moduly Angular

Gdzie w tym wszystkim są kontrolery.

Musimy przypisać każdy kontroler do naszego modułu.

var MainController = function ($scope, $http) {

    var onRequestCompleted = function (response) {
        $scope.user = response.data;
    }

    var onError = function (reason) {
        $scope.error = "Nie można pobrać informacji"
    }

    $http.get("https://api.github.com/users/PanNiebieski").
        then(onRequestCompleted,onError);

}

app.controller("MainController", MainController);

Później by użyć tego modułu w dyrektywie ng-app, która jak do tej pory była pusta wpisujemy nazwę naszego modułu.

<body>
    <div ng-app="KursAngular">
        <div ng-controller="MainController">

To jeszcze nie wszystko.

Musimy jeszcze nasze moduły i kontrolery odsunąć od globalnej przestrzeni nazw. Moduł sam tego nie zrobi.

Jedna z technik polega na otoczeniu kodu funkcją, która automatycznie się wykona przy uruchamianiu strony.

(function () {
    var app = angular.module("KursAngular", []);

    var MainController = function ($scope, $http) {

        var onRequestCompleted = function (response) {
            $scope.user = response.data;
        }

        var onError = function (reason) {
            $scope.error = "Nie można pobrać informacji"
        }

        $http.get("https://api.github.com/users/PanNiebieski").
            then(onRequestCompleted, onError);

    }

    app.controller("MainController", MainController);

})();

W innych aplikacjach Angular można zauważyć, że w metodzie “controller” oprócz kontrolera jest deklarowane coś więcej.

Poniżej widzimy tablicę elementów. Widzimy, że w tej tablicy są zadeklarowane zmienne, które będą potrzebne dla obecnego kontrolera.

app.controller("MainController", ["$scope", "$http", MainController]);

Po co je jednak podawać. Otóż ten zapis rozwiązuje pewien problem związany z minimalizacją plików JavaScript.

Nie próbuj wklejać tego kodu. Oto przykład jak kod JavaScript wygląda po tym procesie.

(function () {
    var n = angular.module("Kurs", []),
        t = function (n, t)
        {
            var i = function (t) { n.user = t.data },
              r = function () { n.error = "Nie można pobrać informacji" };
            t.get("https://api.github.com/users/PanNiebieski").then(i, r)
        }; n.controller("MainController", ["$scope", "$http", t]);
    n.controller("MainController", ["$scope", "$http", t])
})();

Każdy znak w pliku to dodatkowy bajt, który musi zostać pobrany przez przeglądarkę. Proces minimalizacji usuwa białe znaki oraz zamienia zmienne na pojedyncze litery.

Zamienia on także parametry kontrolera z “$scope” i “$http” na pojedyncze litery.

Normalnie przez to aplikacja przestałaby działać. Dzięki jednak odpowiedniemu zdefiniowaniu kontrolera w module, ten problem został rozwiązany.

app.controller("MainController", ["$scope", "$http", MainController]);