Trudny / egzaminacyjny · lekcja 9
Angular I — architektura komponentowa i szablony
Czas na główny framework tego działu. Angular to sposób budowania interfejsu z małych, niezależnych "klocków" (komponentów), które można łączyć w większe całości — dokładnie ta sama idea, co komponenty Blazor, do których być może zajrzysz w dodatkowym bloku na...
Zacznij tutaj
Po co się tego uczymy?
Wprowadzenie
Teoria
Komponent — podstawowa jednostka budowy w Angularze. Każdy fragment interfejsu (przycisk, formularz, cała strona) to komponent — trójka powiązanych plików: .ts (logika w TypeScript), .html (szablon — widok), .css (style TYLKO dla tego komponentu, nie wyciekające do reszty aplikacji). Widziałeś to już pobieżnie w lekcji 4 — teraz czas zrozumieć to dokładnie.
Dekorator @Component. Nad klasą komponentu w TypeScript umieszcza się dekorator (specjalną adnotację) opisującą metadane komponentu:
| Właściwość dekoratora | Znaczenie |
|---|---|
selector | nazwa znacznika HTML, pod którym ten komponent można wstawić w INNYM komponencie, np. <app-produkt></app-produkt> |
standalone: true | nowoczesny styl komponentu — nie wymaga rejestracji w dodatkowym pliku "modułu" (starszy styl Angulara) |
imports: [...] | lista innych komponentów/modułów, z których TEN komponent korzysta w swoim szablonie |
templateUrl / template | ścieżka do pliku .html (albo szablon wpisany bezpośrednio jako string) |
styleUrl / styleUrls | ścieżka do pliku(ów) .css z lokalnymi stylami |
Interpolacja — wypisywanie wartości w szablonie. Podwójne klamry {{ wyrazenie }} wypisują wartość pola/właściwości z klasy TypeScript bezpośrednio w HTML — bezpośredni odpowiednik @Model.Właściwość z Razor albo @zmienna z Blazor: <h1>{{ tytul }}</h1>.
Dyrektywy strukturalne — @if i @for. Nowoczesny Angular (od wersji 17+) wprowadza własną, wbudowaną składnię sterowania renderowaniem, bardzo podobną do Razor/Blazor:
| Składnia | Działanie |
|---|---|
@if (warunek) { ... } @else { ... } | warunkowe renderowanie fragmentu szablonu |
@for (item of lista; track item.id) { ... } | pętla renderująca fragment DLA KAŻDEGO elementu tablicy — track wskazuje unikalny identyfikator, pomagający Angularowi efektywnie odświeżać listę |
@switch (wartosc) { @case (x) { ... } @default { ... } } | wybór jednego z kilku wariantów renderowania |
(Starsze projekty Angular używają zamiast tego dyrektyw *ngIf i *ngFor — działają identycznie, ale wymagają importu CommonModule; nowa składnia @if/@for jest wbudowana i zalecana w nowych projektach).
Komponenty potomne — komunikacja między "klockami". Duży komponent (np. lista produktów) może w swoim szablonie użyć MNIEJSZYCH komponentów (np. pojedynczej karty produktu) — <app-karta-produktu></app-karta-produktu> — dokładnie ta sama idea, co komponenty potomne w Blazor, tylko w składni Angulara; pełne przekazywanie danych między nimi (@Input/@Output) poznasz w kolejnej lekcji.
Zobacz zależności
Schemat
Plik .ts (logika, TypeScript) Plik .html (szablon, widok)
@Component({ <h1>{{ tytul }}</h1>
selector: "app-produkty", │
templateUrl: "./produkty.html" @if (produkty.length === 0) {
}) <p>Brak produktów.</p>
export class ProduktyComponent { } @else {
tytul = "Lista produktów"; <ul>
produkty = [...]; @for (p of produkty; track p.id) {
} <li>{{ p.nazwa }} - {{ p.cena }} zł</li>
│ }
│ łączy dane z widokiem </ul>
└──────────────────────────────► }
Komponent nadrzędny: Komponent potomny:
<app-lista-produktow> <app-karta-produktu>
używa wewnątrz szablonu: (osobny plik .ts + .html + .css)
<app-karta-produktu></app-karta-produktu>
Połącz z praktyką
Przykład z życia
Strona sklepu internetowego zbudowana w Angularze to dziesiątki małych komponentów: nagłówek, stopka, karta produktu (powtórzona wielokrotnie na liście), formularz wyszukiwania — każdy z nich to osobny, niezależny "klocek", który można rozwijać i testować oddzielnie, a potem złożyć w całość, dokładnie tak jak klocki LEGO składają się w większą konstrukcję.