Projekt i implementacja systemów webowych

Wykład 5: Tworzenie aplikacji SPA w Angularze

mgr inż. Maciej Małecki

Architektura aplikacji SPA

Rich Front Architecture

Popularne frameworki

react ng vue

Angular: historia

ng
  • AngularJS - Google, 2010
  • AngularJS: LTS ⇝ 2021-12-31
  • Angular 2.0 - Google, 2016
  • Brak kompatybilności między Angular i AngularJS
  • UWAGA: zwracajcie uwagę na nazwy przeszukując zasoby sieciowe

Angular: architektura

Angular Architecture

Angular: środowisko developerskie

  • Node - środowisko uruchomieniowe dla JavaScript
  • NPM - ang. Node Package Manager - zarządzanie zależnościami
  • NPM registry - repozytorium bibliotek
  • TypeScript - podstawowy język programowania dla Angular 2.x+
  • Angular CLI - narzędzie linii poleceń wspierające proces tworzenia i budowania
  • Karma, Jasmine, JEST, Protractor, Cypress - środowisko tworzenia testów

Środowisko developerskie w praktyce

Instalacja node ⇝ nvm

Instalacja Angular CLI


            npm install -g @angular/cli
          
Angular CLI

Wygenerowanie aplikacji Angular


            $ ng new
            ? What name would you like to use for the new workspace and initial project? foo
            ? Do you want to enforce stricter type checking and stricter bundle budgets in the workspace?
            This setting helps improve maintainability and catch bugs ahead of time.
            For more information, see https://angular.io/strict Yes
            ? Would you like to add Angular routing? Yes
            ? Which stylesheet format would you like to use? SCSS   [ https://sass-lang.com/documentation/syntax#scss                ]
          

Zbudowanie aplikacji


          ng build --prod
        

Uruchomienie aplikacji


          ng serve -o
        

Angular: podstawowe elementy

Moduły
Komponenty
Dyrektywy
Serwisy
Router
Formularze

Moduł (NgModule)

  • funkcjonalny blok aplikacji,
  • sposób organizacji kodu,
  • sposób zarządzania zależnościami,
  • tworzenie kodu bibliotecznego,
  • lazy-loading w przypadku dużych aplikacji.

Moduł ECMA Script oraz Moduł Angulara to dwie różne rzeczy!


          @NgModule({
            imports: [CommonModule],
            declarations: [
              MyComponent1,
              MyComponent2,
              MyExternalComponent3
            ],
            exports: [MyExternalComponent3]
          })
          export class MyModule {
          }
          
  • @NgModule - dekorator TypeScript
  • komponenty "należą" do modułu
  • publiczne elementy modułu należy wyeksportować
Angular Project Structure in IDE Angular Application Composition
  • Struktura katalogów może odzwierciedlać strukturę modułów.
  • Przydaje się moduł general lub shared.

Komponenty "standalone"

  • Moduły są opcjonalne począwszy od Angulara 14.
  • Komponenty, dyrektywy oraz "pipes" można zadeklarować jako standalone.
  • Komponenty mogą od teraz importować moduły.
  • Komponenty (dyrektywy, "pipes") są self-contained.

Komponent

  • Komponent jest podstawową jednostką budowania warstwy wizualnej aplikacji.
  • Komponent może być wykorzystywany wielokrotnie.
  • Komponent komunikuje się ze światem "zewnętrznym" w ściśle określony sposób.

          ng generate component user-mgmt/user-list
        
User list component User list component declaration
  • html - szablon - część wizualna, ang. template (opcja)
  • scss - prywatny arkusz styli (opcja)
  • component.ts - kod/kontroler komponentu
  • spec.ts - testy jednostkowe komponentu (opcja)

Definicja wyglądu komponentu w HTML:


          

lub z użyciem zewnętrznego pliku:

user-list.component.html

Model DOM

DOM (Document Object Model) jest to model obiektowy reprezentujący dokument HTML wyświetlany przez przeglądarkę.

Przeglądarka buduje DOM w pamięci za każdym razem, gdy wyświetla HTML.

Każdy skrypt JavaScript (a więc także i każda aplikacja Angular) wchodzi w interakcję z DOM.

Postawowe API elementów DOM:

atrybut dodatkowa wartość definiująca tag (w dokumencie HTML)
właściwość (property), właściwość obiektu DOM (zwykła właściwość obiektu w JS)
metoda funkcja obiektu DOM, którą można wywołać
zdarzenie (event) - informacja o zaistnieniu pewnego faktu, np click, focus, blur

Data binding - wiązanie danych

Data binding są to mechanizmy pozwalające na integrację modelu z widokiem.

{{interpolation}} wyliczy wyrażenie wewnątrz {{}} oraz wstawi wartość
[property_binding] Angular będzie aktualizował wartość właściwości na podstawie wyrażenia
(event_binding) wywołana zostanie funkcja w reakcji na zaistnienie zdarzenia
[(two_way_binding)] synchronizuje model z widokiem "w obie strony"

Detekcja zmian

Change detection

Cykl życia komponentu

Cykl życia komponentu

Dyrektywy

Dyrektywy to elementy rozszerzające funkcjonalność HTML, które można deklarować za pomocą Angular.

Istnieją trzy rodzaje dyrektyw:

  • Komponenty (już je znamy)
  • Dyrektywy atrybutowe
  • Dyrektywy strukturalne

Dyrektywy atrybutowe

  • ngModel - wiążą pola edycyjne z modelem
  • ngClass - pozwalają dynamicznie modyfikować klasy CSS
  • ngStyle - pozwalają dynamicznie modyfikować style CSS

Dyrektywy atrybutowe


          divClasses = {};
          ...
          this.divClasses: {
            'valid': this.isValid(),
            'highlighted': this.isHighlighted()
          }
        

W prostszych przypadkach...

Dyrektywy strukturalne

*ngIf - dodaje/usuwa element z DOM:

*ngfor - iteruje po liście i dodaje element DOM dla każdego elementu listy:

ngSwitch, *ngSwitchCase, *ngSwitchDefault - odpowiednik instrukcji switch/case/default z innych języków programowania.

Komunikacja międzykomponentowa

Angular pozwala na stosowanie data bindings we własnych komponentach.

Dla danych wejściowych:


          export class UserDetailsComponent
          {
             ...
             @Input() user: User;
             ...
          }
        

Dla danych wyjściowych:


          export class UserDetailsComponent
          {
             ...
             @Output() onChanged = new EventEmitter<User>();
             ...
             this.onChanged.emit(user);
             ...
          }
        

Required inputs

  • Nowość począwszy od Angulara 16
  • @Input({required=true})
  • Wiązanie musi być określone, inaczej nastąpi błąd kompilacji.

Input tranforms

  • Nowość począwszy od Angulara 16
  • @Input({transform: booleanAttribute})
  • Funkcja transformująca wartość.

Routing

Jak działa przeglądarka?

  • Obsługa pola adresowego URL
  • Hiperlinki i przekierowania
  • Historia przeglądania

Router jest modułem Angulara, który implementuje podstawowe funkcje przeglądarki (URL, historia) w aplikacjach typu Single-Page.

Routing setup
  • Router to opcjonalny moduł Angulara
  • Jedna instancja routera dla aplikcji
  • Router inicjujemy tzw. tablicą przejść (ang. routes)
Routing reorganized Router outlet source

router-outlet określa miejsce, w którym Router będzie "wklejał" nasz komponent.

Router outlet

Więcej informacji na https://angular.io/guide/router.

Serwis

Serwis to współdzielony kod aplikacji:

  • może posiadać stan
  • posiada zasięg (scope) oraz cykl życia
  • podlega mechanizmowi DI (dependency injection)

          @Injectable()
          export class UserService {

            users: User[] = [];

            constructor() {
              this.users = [
                {id: 1, name: 'John Doe', email: 'john.doe@email.com'},
                {id: 2, name: 'Max Rockatansky', email: 'mad.max@email.com'},
                {id: 3, name: 'Chuck Peddle', email: 'chuck@mos.com'}
              ];
            }

            getAllUsers() {
              return this.users;
            }

            saveUser(user: User) {
              const found = this.findUser(user.id);
              if (found) {
                Object.assign(found, user);
              } else {
                this.users.push(user);
              }
            }

            findUser(id: number) {
              return this.users.find((user: User) => user.id === id);
            }

            getNextId() {
              return this.users
                .map((elem: User) => elem.id)
                .reduce((prev, curr) => prev > curr ? prev : curr, 0) + 1;
            }
          }
        

HttpClient

Architektura Smart-Dumb

Smart-Dumb

Bibliografia

Przykładowa aplikacja

https://github.com/pwr-piisw/ng-bookstore