Kurs Angular · Moduł 4: Routing
Trasy zagnieżdżone i resolve - pokoje w dojo
W tej lekcji2
Dojo nie jest jedną salą - to budynek z pokojami wewnątrz pokojów: sala treningowa, a w niej kącik broni, a w nim profil konkretnego samuraja. Trasy w Angularze zagnieżdżają się tak samo. W tej lekcji poznasz dwie rzeczy: jak budować trasy w trasach (parent i children) oraz jak resolverem pobierać dane, zanim ekran się pokaże.
Trasy dzieci - ścieżki w ścieżkach
Trasa może mieć children - podtrasy, które renderują się wewnątrz rodzica. Zobacz, jak /dojo zawiera trening i broń, a profil samuraja ma własne zakładki.
export const routes: Routes = [
{
path: 'dojo',
component: DojoLayoutComponent,
children: [
{ path: '', component: DojoHomeComponent },
{ path: 'training', component: TrainingComponent },
{
path: 'samurai/:id',
component: SamuraiProfileComponent,
children: [
{ path: '', redirectTo: 'info', pathMatch: 'full' },
{ path: 'info', component: SamuraiInfoComponent },
{ path: 'skills', component: SamuraiSkillsComponent }
]
}
]
}
];Czytaj to jak plan budynku: /dojo/training to sala treningowa w dojo, a /dojo/samurai/5/skills to zakładka umiejętności w profilu samuraja numer 5. Zwróć uwagę na dwie sztuczki: pusta ścieżka { path: '' } to widok domyślny rodzica (co pokazać, gdy nikt nie wybrał podtrasy), a redirectTo: 'info' przekierowuje z profilu wprost na zakładkę info, żeby ekran nigdy nie był pusty.
Żeby dzieci miały się gdzie renderować, rodzic musi mieć własny router-outlet:
@Component({
template: `
<header>
<h1>Dojo</h1>
<nav><a routerLink="training">Trening</a></nav>
</header>
<router-outlet></router-outlet>
`
})
export class DojoLayoutComponent { }To sedno zagnieżdżania: DojoLayoutComponent rysuje wspólną ramę (nagłówek, nawigację), a <router-outlet> to okno, w którym pojawia się aktywne dziecko. Wchodzisz na /dojo/training - w oknie renderuje się TrainingComponent, ale nagłówek dojo zostaje. Każdy poziom zagnieżdżenia ma swój outlet, jak pokój w pokoju.
Resolver - dane zanim wejdziesz
Domyślnie komponent ładuje się od razu, a dane dociągasz w ngOnInit - przez chwilę ekran jest pusty. Resolver odwraca kolejność: pobiera dane zanim trasa się aktywuje, więc komponent od pierwszej klatki ma komplet.
import { ResolveFn } from '@angular/router';
export const samuraiResolver: ResolveFn<Samurai> = (route) => {
const service = inject(SamuraiService);
const id = route.paramMap.get('id')!;
return service.getById(+id);
};
// W definicji trasy
{
path: 'samurai/:id',
component: SamuraiDetailComponent,
resolve: { samurai: samuraiResolver }
}Resolver to funkcja, która zwraca dane dla trasy - tu pobiera samuraja po id z adresu. Angular czeka, aż dane przyjdą, i dopiero potem pokazuje komponent. Dzięki temu nie zobaczysz migającego pustego profilu. W komponencie odbierasz gotowe dane wprost z trasy:
export class SamuraiDetailComponent {
private route = inject(ActivatedRoute);
samurai = this.route.snapshot.data['samurai'] as Samurai;
}Klucz samurai w data to dokładnie ta nazwa, którą nadałeś w resolve: { samurai: ... }. Zamiast wołać serwis i obsługiwać stan ładowania w komponencie, po prostu czytasz gotowy obiekt. Kompromis jest świadomy: użytkownik czeka moment dłużej na przejście, ale nie widzi pustego ekranu - dobre do stron, które bez danych nie mają sensu.
Pamiętaj z tej lekcji dwie rzeczy: trasy zagnieżdżają się przez children i renderują w router-outlet rodzica, jak pokoje w dojo; a resolver pobiera dane przed wejściem, by komponent nigdy nie startował pusty.
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Jak definiujemy zagnieżdżone trasy w Angular?
2. Gdzie renderują się komponenty tras-dzieci (children)?
To 2 z 5 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Układanie w pionie
Uporządkuj linie definicji trasy rodzica z dziećmi (od góry do dołu, jak w edytorze):
- Edytor kodu
Uzupełnij konfigurację z zagnieżdżonymi trasami dla DashboardComponent.
- Klikanie w kolejności
Zbuduj właściwość resolve podpinającą resolver pod klucz 'samurai':