architektura
omówię:
- wstęp do architektury
- podstawowy podział: komponent, moduł, serwis
architektura
Po stworzeniu projektu warto by było go otworzyć w IDE. Polecam InteliJ Ultimate lub WebStorm ewentualnie Visual Studio Code.
Spójrzmy na strukturę projektu i zorientujmy się co za co odpowiada.
package.json – plik do zarządzania zależnościami. Tam dodajemy biblioteki które chcemy dołączyć do naszego projektu. Plik analogiczny jak pom.xml w Springu. Masz dwie możliwości aby dodać zależności do projektu.
1) Ręczne dodanie wpisu do package.json
2) Poprzez konsole i polecenie npm i
node modules – wszystkie zależności. W tym folderze znajdują się wszystkie zależności i biblioteki, które są zdefiniowane w pliku package.json. Folder analogiczny mniej więcej jak .m2 dla Mavena.
src – główny folder z naszymi plikami do aplikacji. W nim będziemy tworzyć nowe komponenty, klasy, szablony html css itd.
index.html – główna strona HTML wyświetlana, gdy ktoś odwiedza Twoją witrynę. Interfejs CLI automatycznie dodaje wszystkie pliki JavaScript i CSS podczas tworzenia aplikacji, więc zazwyczaj nie trzeba ręcznie dodawać żadnych tagów
Trzy główne elementy jakie możemy spotkać w Angularze to:
KOMPONENT
MODUŁ
SERWIS
komponent
Wejdź do pliku app.component.ts. Jest to pierwszy komponent jaki poznasz w Angularze, ponieważ jest on generowany automatycznie.
W Angularze aplikacja składa się z tzw. drzewa komponentów. Komponent może posiadać kilka komponentów „dzieci” oraz jednego rodzica. Aplikacja posiada jeden główny komponent AppComponent, który jest tzw. root-component.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'first-project';
}
Adnotacja @Component pozwala ustawić w projekcie daną klasę jako komponent. Adnotacja w Anglarze pozwala na dodanie metadanych do klasy. Dzięki tej adnotacji Angular wie, jak traktować daną klasę.
Czym cechuje się komponent ?
– musi posiadać unikalną identyfikację jako tag html’owy czyli tzw. selctor. Jeżeli będziesz chciał użyć w szablonie HTML’owym komponentu jest to bardzo proste. Wystarczy, że użyjesz nazwy z selector’a w formie tagu czyli po prostu <app-root></app-root>. Więcej szczegółów podam później w miarę rozbudowy naszej aplikacji. Konwencja nazewnicza dla selector’a: app-nazwaKomponentu przy czym każde słowo w nazwie komponentu powinno być oddzielone myślnikiem.
– musi posiadać szablon HTML czyli templateUrl. Jest to namiar na szablon HTML jako odrębny plik. Istnieje także możliwość wpisania kodu HTML bezpośrednio w naszym komponencie dzięki operatorowi back-tick ` (ten pod tyldą ~ i ten obok wykrzyknika). Nie będę tego prezentował, ponieważ nie jest to dobra praktyka i praktycznie się z tego nie korzysta. TemplateUrl przyjmuje tylko jeden parametr, nie możemy przekazać kilku plików HTML.
– opcjonalnie ustawienie styli dla komponentu czyli styleUrls. (Istnieje także opcja styles ale pominę ją ze względów jak powyżej. Nie jest to dobra praktyka). StylesUrls jest tablicą styli i możemy przekazać tutaj kilka plików css.
moduł
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Moduł pozwala na organizowanie niezbędnych zasobów w ramach danego obszaru biznesowego/funkcjonalnego. Głównym modułem w aplikacji jest AppModule. Wszystkie zasoby (komponenty, serwisy, moduły itd) muszą bezpośrednio bądź pośrednio (za pośrednictwem innych modułów) znaleźć się w głównym module AppModule aby można było z nich korzystać. Omówmy podział modułu.
– declarations – w tym miejscu definiujesz komponenty, pipe, dyrektywy
– imports – służy do definiowania innych modułów
– providers – tutaj definiujesz serwisy
serwis
Serwis jest odpowiedzialny za część logiki biznesowej. Tak samo jak w Javie serwisy w Angularze są domyślnie singletonami. Możesz użyć serwisu jeżeli chcesz przechowywać jakiś stan albo pobrać dane z backendu
Podczas generowania projektu nie został utworzony żaden serwis. Stwórzmy go zatem sami. Aby to zrobić utwórz w katalogu src katalog context. Następnie w konsoli przejdź do tego katalogu i wpisz komendę:
ng g s context <- wersja skrócona
(ng generate service context)
Zostaną utworzone dwa pliki:
context.service.spec.ts oraz context.service.ts.
context.service.spec.ts możesz usunąć, ponieważ jest to automatycznie wygenerowany plik przeznaczony do testów jednostkowych. Testami póki co nie będziemy się zajmować.
Rzeczą która rzuca się w oczy jest element: providedIn: root. Jest to sposób definiowania widoczności serwisu w obrębie danego modułu. Jeżeli ustawisz root, serwis będzie dostępny w całej aplikacji. Przykład użycia i wykorzystania serwisu omawialiśmy w tym artykule.
import { Injectable } from '@angular/core';
@Injectable(
{
providedIn: 'root'
}
)
export class CarService {
private carsWithoutDiscount = ['A8', 'Seria 7', 'Klasa S'];
private carsDiscount: Map<string, number> = new Map([
['A6', 20],
['Klasa E', 15],
['Seria 5', 17],
]);
getCarDiscount(carModel: string): number {
return this.carsDiscount.get(carModel);
}
getCarsWithoutDiscount(): string[] {
return this.carsWithoutDiscount;
}
}