Projekt startowy AngularJS

Na początek opowiemy kilka słów o podstawowych elementach AngularJS na przykładzie aplikacji startowej, dostępnej do ściągnięcia ze strony naszego bloga Projekt startowy Spring Boot + AngularJS. Projekt, który jest spakowany do pliku zip, można tam pobrać na dole strony, zaraz pod fragmentami kodu.

Struktura projektu AngularJS

Typowy projekt AngularJS charakteryzuje się uporządkowaną strukturą składników, do których należą elementy takie jak moduł, kontroler, dyrektywa, fabryka, serwis, itp. (więcej piszemy w trakcie kursu). W ramach struktury każdy ze składników posiada swoje dedykowane przeznaczenie, dlatego wskazane jest wydzielenie tych elementów do osobnych plików. Nazewnictwo plików może być dowolne, niemniej w naszych projektach przyjmujemy nazwy podobne do tych, które możecie zobaczyć w bieżącym rozdziale. Przykładowo plik z głównym modułem aplikacji nazywamy app.js, a plik z routingiem to zawsze router.js. Aby jednak w ogóle było możliwe korzystanie z AngularJS, wymagane jest podpięcie odpowiednich bibliotek w pliku startowym HTML naszej aplikacji. Plik ten nosi standardową nazwę - index.html.

Zobaczmy więc teraz jak wygląda pełna lista składników wymaganych do stworzenia aplikacji AngularJS:
  • Biblioteki jQuery i AngularJS - Zbiór plików, które dostarczą nam jQuery (w AngularJS korzystamy czasem z bibliotek, które są oparte o biblioteki jQuery) oraz podstawową implementację AngularJS wraz z ewentualnymi bibliotekami dodatkowymi:
    <script src="vendor/jquery/jquery-x.x.x.min.js"></script>
    <script src="vendor/angular/angular.min.js"></script>
    <script src="vendor/angular/angular-strap.min.js"></script>
    <script src="vendor/angular/angular-strap.tpl.min.js"></script>
    <script src="vendor/angular/angular-messages.min.js"></script>
    <script src="vendor/angular/angular-resource.min.js"></script>
    <script src="vendor/angular/angular-ui-router.min.js"></script>
    ...
    
  • Plik startowy HTML - Standardowy plik HTML o nazwie: index.html, który zawiera dodatkowe atrybuty HTML nazywane dyrektywami:
    • ng-app - dyrektywa informująca przeglądarkę (a dokładniej framework AngularJS), że w tym miejscu rozpoczyna się aplikacja AngularJS (moduł aplikacji):
      <html ng-app="Appa">
      
      O dyrektywach wbudowanych we framework AngularJS, w tym o dyrektywie ng-app, piszemy więcej w rozdziale Dyrektywy wbudowane.
    • ng-controller - dyrektywa, która jeśli jest podana w tagu body, wskazuje na kontroler całego zakresu działania aplikacji (root scope), a więc dla wszystkich elementów, które będą dodawane do strony. Podana nazwa AppCtrl to nazwa kontrolera zdefiniowanego najczęściej w pliku app-controller.js (albo app.controller.js - taką wersję nazwy przyjmujemy w naszych kursach, choć tak naprawdę nazwa może być dowolna):
      <body ng-controller="AppCtrl">
      
      O kontrolerach piszemy szerzej w rozdziale: Kontroler (Controller).
    • ui-view - miejsce gdzie będą wstawiane widoki kolejnych stron (a dokładniej stanów) odwiedzanych przez użytkownika (np. przechodząc do stanu zdefiniowanego w $stateProvider jako 'home' zostanie wstawiona tutaj zawrtość pliku określona jako templateUrl: 'postspringular/home/home.html'):
      <div ui-view></div>
      
      Więcej na temat samej dyrektywy ui-view jak i o zarządzaniu stanami piszemy w rozdziale Dostawca stanu i dyrektywa ui-view.
  • Moduł aplikacji - Plik o nazwie (również zwyczajowej): app.js, który zawiera funkcję:

    angular.module(<NAZWA_MODUŁU>, <[INNE MODUŁY]>)

    Plik z modułem reprezentuje naszą aplikację jako całość (traktując ją jako niezależny moduł) oraz umożliwia podpinanie innych modułów, z których korzysta lub będzie korzystać aplikacja.
    angular.module(
        'Appa',
        ['home', 'mgcrea.ngStrap', 'ui.router', 'ui.bootstrap']);
    
    Plik app.js jest dobry miejscem do tego aby definiować wszystkie rozwiązania, które mają działać globalnie, dla całej aplikacji. Tak więc tutaj znajdą się na przykład filtry, stałe czy też usługi alb dostawcy (providers), których zadaniem jest wykonywanie operacji niezwiązanych z konkretnym submodułem aplikacji, a dotyczących raczej aplikacji jako całości.
    angular.module('Appa').config(function($logProvider) {
    
        ...
    
    });
    
    angular.module('Appa').filter('propsFilter', function() {
        return function(items, props) {
        	
        	...
        };
    });
    
    angular.module('Appa').factory('User', [ '$http', function($http) {
    
        $http.defaults.headers.common['Content-Type'] = ...
    
    } ]);
    
    angular.module('Appa').constant('AppaConf', {
    
        confUrl : 'http://...'
        
    });
    
  • Router - Plik o nazwie: router.js, który zawiera dodatkową konfigurację modułu:

    angular.module(<NAZWA_MODUŁU>).config(['$stateProvider', '$urlRouterProvider', function(...) {...}])

    Plik ten, poprzez zastosowanie odpowiednich dostawców stanu oraz routingu, jest odpowiedzialny za wiązanie adresów URL z konkretnymi kontrolerami oraz widokami, dzięki czemu użytkownik aplikacji udając się do określonego stanu jest kierowany na konkretny URL oraz powiązany z nim widok. Użytkownik ma wrażenie, że pod określonymi adresami znajdują się osobne strony generowane i wysyłane przez serwer, podczas gdy tak naprawdę przebywa on ciągle na jednej i tej samej stronie, a podmienianie widoków odbywa się po stronie przeglądarki w JS.
    angular.module('Appa').config(['$stateProvider', '$urlRouterProvider', 
                                    function($stateProvider, $urlRouterProvider) {
                                    
        $stateProvider.state('home', {
            url : '/',
            templateUrl : 'postspringular/home/home.html',
            controller : 'HomeCtrl'
        });
        $urlRouterProvider.otherwise('/');
    
    } ]);
    
    Jak widać plik routera zawiera odwołanie do modułu aplikacji, na którym to module wykonywana jest funkcja config. Jej parametrami są dwa mechanizmy zarządzania ruchem: $stateProvider i $urlRouterProvider. Pierwszy wykonuje właściwe wiązanie widoku z URL, a drugi przekierowuje ruch zawsze na stronę główną (dla każdego nieznanego adresu).

    Wykonane wiązanie opisane jest nazwą, która określa stan (state) aplikacji. Używając stosownych mechanizmów AngularJS, o których będzie jeszcze mowa w tym kursie, możemy poinformować framework, że chcemy udać się do tego stanu, a on wstawi w adresie przeglądarki podany URL oraz pokaże użytkownikowi zdefiniowany w tym stanie widok ('../home.html'). Dodatkowo zostanie wtedy wykonany kod JS zawarty w kontrolerze o wskazanej nazwie - 'HomeCtrl'.

    Temat stanów i przechodzenia między nimi jest bardzo ważny i dlatego należy go dobrze zrozumieć. Stąd też poświęcamy mu większość dedykowanego rozdziału Dostawca stanu i dyrektywa ui-view.
  • Kontroler aplikacji - Plik o nazwie: app-controller.js, który zawiera podstawowy kontroler aplikacji (wspominany przez nas wyżej w kontekście dyrektywy ng-controller):

    angular.module(<NAZWA_MODUŁU>).controller(
    <NAZWA_KONTROLERA>, [<WSTRZYKIWANE_ZALEŻNOŚCI>, function(<WSTRZYKIWANE_ZALEŻNOŚCI>) {...}])


    Bazowy kontroler, w którym zgodnie z dobrymi praktykami, sprawujemy kontrolę nad głównym zakresem (root scope) naszej aplikacji. Wszystkie inne zakresy kolejnych kontrolerów będą zakresami potomnymi zakresu głównego i będą posiadały swoje własne kontrolery. W naszym przykładzie na blogu - dzięki zastosowanym kolorom - dobrze widać jak wygląda relacja zakresu całej aplikacji definiowanego w app-controller.js do zakresu potomnego strony głównej.
    angular.module('Appa').controller('AppCtrl',
        ['$rootScope', ..., function($rootScope, ...) {
    
            $scope.rootScopeLabel = "root scope";
    } ]);
    
    Charakterystyczne dla kontrolerów jest to, że mogą one przyjmować inne obiekty tworzone przez framework, korzystając przy tym z mechanizmu wstrzykiwania zależności. Tak więc programista nie musi tworzyć kluczowych obiektów własnoręcznie, tylko zrzuca tą odpowiedzialność na framework. Wstrzykiwanie zależności jest realizacją koncepcji IOC (Inversion Of Control), którą dokładniej opisujemy w jednym z początkowych rozdziałów Kursu Spring.

    Przypominamy, że więcej o kontrolerach znajdziecie w rozdziale Kontroler (Controller).
Zobaczmy teraz jak powyższy zestaw wygląda w konkretnym projekcie:
Rekomendacja
Domyślnie AngularJS zawiera wbudowanego dostawcę routingu w postaci $routeProvider-a. My używamy $stateProvider-a, który jest częścią dodatkowego modułu ui.router. Warto zastosować takie rozwiązanie, ponieważ dzięki temu zyskujemy kilka benefitów, z których najważniejsze to:
  • Możemy używać wielu dyrektyw ui-view (miejsce do wstawienia widoku) na stronie.
  • Możemy korzystać z zagnieżdżania widoków i utrzymywać je poprzez określenie stanu w fazie routingu.
Nie zawsze będziemy potrzebować powyższych funkcjonalności, ale też z drugiej strony nigdy nie wiemy jakie wymaganie pojawi się w trakcie realizacji projektu, a późniejsza przebudowa może przysparzać problemy. Warto więc skorzystać ze $stateProvider-a, tymbardziej, że nie generuje to wiele dodatkowego kodu.
Używamy w StartAPPa


Wszystkie projekty składające się na aplikację zawierają strukturę taką jak przedstawiona w tym rozdziale. Posiadają one jednak znacznie większą liczbę modułów, co spowodowane jest potrzebą użycia dodatkowych, zewnętrznych funkcjonalności. Przykładowo w ramach rozwiązania Tabela Zaawansowana dodajemy moduły takie jak datatables (komponent tabelki) oraz ngDialog (dialog do usuwania itemów):
angular.module(
        'Appa',
        [ 'ui.router', 'angular-growl', 'mgcrea.ngStrap', 'datatables', 
            'datatables.buttons', 'ngDialog', 'home',
            'shared', 'appa.grid.server' ]);
Projekt appaform, przedstawiony na obrazku, pochodzi z modułu Formularz Zaawansowany i zawiera kod budowy formularza z dużą ilością różnorodnych komponentów najczęściej spotykanych podczas tworzenia formularzy na potrzeby biznesowe. Linki:
https://angularjs.org
https://docs.angularjs.org/api
https://itexpertsconsultant.wordpress.com/2016/01/25/routeprovider-vs-stateprovider-in-angularjs

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