Kompletny przewodnik po routingu w Angular
Opublikowany: 2022-03-10Jeśli nadal nie jesteś zaznajomiony z Angularem 7, chciałbym przybliżyć Ci wszystko, co ten imponujący front-endowy framework ma do zaoferowania. Przeprowadzę Cię przez aplikację demonstracyjną Angular, która pokazuje różne koncepcje związane z routerem, takie jak:
- gniazdo routera,
- Trasy i ścieżki,
- Nawigacja.
Pokażę Ci również, jak za pomocą Angular CLI v7 wygenerować projekt demonstracyjny, w którym użyjemy routera Angular do zaimplementowania routingu i nawigacji. Ale najpierw pozwól, że przedstawię Ci Angulara i omówię niektóre z ważnych nowych funkcji w jego najnowszej wersji.
Przedstawiamy Angular 7
Angular to jedna z najpopularniejszych platform front-endowych do tworzenia aplikacji internetowych po stronie klienta dla sieci mobilnych i stacjonarnych. Jest zgodny z architekturą opartą na składnikach, w której każdy składnik jest izolowanym i wielokrotnego użytku fragmentem kodu, który kontroluje część interfejsu użytkownika aplikacji.
Składnik w Angular to klasa TypeScript ozdobiona dekoratorem @Component
. Ma dołączony szablon i arkusze stylów CSS, które tworzą widok komponentu.
Angular 7, najnowsza wersja Angulara została niedawno wydana z nowymi funkcjami, szczególnie w narzędziach i wydajności CLI, takimi jak:
- Podpowiedzi CLI: Popularne polecenie, takie jak
ng add
ing new
, może teraz monitować użytkownika o wybranie funkcji do dodania do projektu, takich jak format routingu i arkuszy stylów itp. - Dodanie przewijania do Angular Material CDK (Component DevKit).
- Dodanie obsługi przeciągania i upuszczania do Angular Material CDK.
- Projekty są również domyślnie używane do korzystania z pakietów budżetowych, które będą ostrzegać programistów, gdy ich aplikacje przekraczają limity rozmiaru. Domyślnie ostrzeżenia są generowane, gdy rozmiar ma więcej niż 2 MB, a błędy wynoszą 5 MB. Możesz również zmienić te limity w pliku
angular.json
. itp.
Przedstawiamy router kątowy
Angular Router to potężny router JavaScript zbudowany i utrzymywany przez główny zespół Angulara, który można zainstalować z pakietu @angular/router
. Zapewnia kompletną bibliotekę routingu z możliwością posiadania wielu gniazd routera, różnych strategii dopasowywania ścieżek, łatwego dostępu do parametrów trasy i ochrony trasy w celu ochrony komponentów przed nieautoryzowanym dostępem.
Router Angular jest podstawową częścią platformy Angular. Umożliwia programistom tworzenie aplikacji jednostronicowych z wieloma widokami i umożliwia nawigację między tymi widokami.
Przyjrzyjmy się teraz bardziej szczegółowo podstawowym pojęciom dotyczącym routerów.
Wyjście routera
Router-Outlet
to dyrektywa dostępna z biblioteki routera, w której router wstawia składnik, który jest dopasowany na podstawie adresu URL bieżącej przeglądarki. Możesz dodać wiele gniazdek w swojej aplikacji Angular, co umożliwia implementację zaawansowanych scenariuszy routingu.
<router-outlet></router-outlet>
Każdy składnik, który zostanie dopasowany przez router, spowoduje, że będzie on rodzeństwem gniazda routera.
Trasy i ścieżki
Trasy to definicje (obiekty) składające się przynajmniej z atrybutów ścieżki i komponentu (lub redirectTo path). Ścieżka odnosi się do części adresu URL, która określa unikalny widok, który powinien być wyświetlany, a komponent odnosi się do komponentu Angular, który musi być powiązany ze ścieżką. Na podstawie dostarczonej przez nas definicji trasy (za pomocą statycznej RouterModule.forRoot(routes)
) router jest w stanie nawigować użytkownika do określonego widoku.
Każda Route
mapuje path
URL do komponentu.
Ścieżka może być pusta, co oznacza domyślną ścieżkę aplikacji i zwykle jest to początek aplikacji.
Ścieżka może przyjmować ciąg znaków wieloznacznych ( **
). Router wybierze tę trasę, jeśli żądany adres URL nie pasuje do żadnych ścieżek dla zdefiniowanych tras. Można to wykorzystać do wyświetlenia widoku „Nie znaleziono” lub przekierowania do określonego widoku, jeśli nie zostanie znalezione dopasowanie.
Oto przykład trasy:
{ path: 'contacts', component: ContactListComponent}
Jeśli ta definicja trasy zostanie podana do konfiguracji routera, router wyrenderuje ContactListComponent
, gdy adres URL przeglądarki dla aplikacji sieci Web stanie się /contacts
.
Strategie dopasowywania tras
Router Angular udostępnia różne strategie dopasowywania tras. Domyślna strategia polega po prostu na sprawdzeniu, czy adres URL bieżącej przeglądarki jest poprzedzony ścieżką .
Na przykład nasza poprzednia trasa:
{ path: 'contacts', component: ContactListComponent}
Można również zapisać jako:
{ path: 'contacts',pathMatch: 'prefix', component: ContactListComponent}
Atrybut patchMath
określa strategię dopasowania. W tym przypadku jest to prefiks , który jest domyślny.
Druga strategia dopasowania jest pełna . Gdy zostanie określony dla trasy, router sprawdzi, czy ścieżka jest dokładnie równa ścieżce adresu URL bieżącej przeglądarki:
{ path: 'contacts',pathMatch: 'full', component: ContactListComponent}
Trasa Param
Tworzenie tras z parametrami to powszechna funkcja w aplikacjach internetowych. Angular Router umożliwia dostęp do parametrów na różne sposoby:
- Korzystając z usługi ActivatedRoute,
- Korzystanie z obserwowalnego ParamMap dostępnego od wersji 4.
Możesz utworzyć parametr trasy, używając składni dwukropka . Oto przykładowa trasa z parametrem id :
{ path: 'contacts/:id', component: ContactDetailComponent}
Strażnicy Trasy
Route Guard to funkcja routera Angular, która pozwala programistom uruchomić pewną logikę, gdy żądana jest trasa, i na podstawie tej logiki zezwala lub odmawia użytkownikowi dostępu do trasy. Jest powszechnie używany do sprawdzania, czy użytkownik jest zalogowany i ma uprawnienia, zanim uzyska dostęp do strony.
Możesz dodać strażnika trasy, implementując interfejs CanActivate
dostępny z pakietu @angular/router
i rozszerzając canActivate()
, która przechowuje logikę zezwalającą lub odmawiającą dostępu do trasy. Na przykład następujący strażnik zawsze zezwoli na dostęp do trasy:
class MyGuard implements CanActivate { canActivate() { return true; } }
Następnie możesz zabezpieczyć trasę strażnikiem za pomocą atrybutu canActivate
:
{ path: 'contacts/:id, canActivate:[MyGuard], component: ContactDetailComponent}
Dyrektywa Nawigacyjna
Router Angular udostępnia dyrektywę routerLink
do tworzenia łączy nawigacyjnych. Ta dyrektywa przyjmuje ścieżkę skojarzoną z komponentem, do którego ma przejść. Na przykład:
<a [routerLink]="'/contacts'">Contacts</a>
Wiele gniazdek i tras pomocniczych
Angular Router obsługuje wiele gniazd w tej samej aplikacji.
Komponent ma jedną powiązaną trasę główną i może mieć trasy pomocnicze. Trasy pomocnicze umożliwiają programistom nawigację wieloma trasami jednocześnie.
Aby utworzyć trasę pomocniczą, potrzebujesz nazwanego gniazda routera, w którym będzie wyświetlany komponent powiązany z trasą pomocniczą.
<router-outlet></router-outlet> <router-outlet name="outlet1"></router-outlet>
- Placówka bez nazwy jest głównym gniazdem.
- Wszystkie gniazdka powinny mieć nazwę, z wyjątkiem gniazdka głównego.
Następnie możesz określić gniazdko, w którym chcesz renderować swój komponent za pomocą atrybutu gniazdka:
{ path: "contacts", component: ContactListComponent, outlet: "outlet1" }
Tworzenie projektu demonstracyjnego Angular 7
W tej sekcji zobaczymy praktyczny przykład konfiguracji i pracy z routerem Angular. Możesz zobaczyć demo na żywo, które będziemy tworzyć, oraz repozytorium GitHub dla projektu.
Instalowanie Angular CLI v7
Angular CLI wymaga węzła 8.9+ z NPM 5.5.1+ . Musisz upewnić się, że masz zainstalowane te wymagania w swoim systemie, a następnie uruchom następujące polecenie, aby zainstalować najnowszą wersję Angular CLI:
$ npm install -g @angular/cli
Spowoduje to globalną instalację Angular CLI.
Uwaga : Możesz chcieć użyć sudo
do globalnego instalowania pakietów, w zależności od konfiguracji npm.
Tworzenie projektu Angular 7
Tworzenie nowego projektu to jedno polecenie, wystarczy uruchomić następujące polecenie:
$ ng new angular7-router-demo
CLI zapyta, czy chcesz dodać routing (wpisz N
dla Nie, ponieważ zobaczymy, jak możemy dodać routing ręcznie) i jakiego formatu arkusza stylów chcesz użyć, wybierz CSS, pierwszą opcję, a następnie naciśnij Enter
. CLI utworzy strukturę folderów z niezbędnymi plikami i zainstaluje wymagane zależności projektu.
Tworzenie fałszywej usługi zaplecza
Ponieważ nie mamy prawdziwego back-endu, z którym można by wchodzić w interakcje, utworzymy fałszywy back-end za pomocą biblioteki angular-in-memory-web-api
, która jest internetowym interfejsem API in-memory dla demonstracji i testów Angulara. emuluje operacje CRUD przez REST API.
Działa poprzez przechwytywanie żądań HttpClient
wysyłanych do zdalnego serwera i przekierowywanie ich do lokalnego magazynu danych w pamięci, który musimy utworzyć.
Aby stworzyć fałszywy back-end, musimy wykonać następujące kroki:
- Najpierw instalujemy moduł
angular-in-memory-web-api
, - Następnie tworzymy serwis zwracający fałszywe dane,
- Na koniec skonfiguruj aplikację tak, aby korzystała z fałszywego zaplecza.
W swoim terminalu uruchom następujące polecenie, aby zainstalować moduł angular angular-in-memory-web-api
z npm:
$ npm install --save angular-in-memory-web-api
Następnie wygeneruj usługę back-end za pomocą:
$ ng gs backend
Otwórz plik src/app/backend.service.ts
i zaimportuj InMemoryDbService
z modułu angular angular-in-memory-web-api
:
import {InMemoryDbService} from 'angular-in-memory-web-api'
Klasa usługi musi zaimplementować InMemoryDbService
, a następnie zastąpić createDb()
:
@Injectable({ providedIn: 'root' }) export class BackendService implements InMemoryDbService{ constructor() { } createDb(){ let contacts = [ { id: 1, name: 'Contact 1', email: '[email protected]' }, { id: 2, name: 'Contact 2', email: '[email protected]' }, { id: 3, name: 'Contact 3', email: '[email protected]' }, { id: 4, name: 'Contact 4', email: '[email protected]' } ]; return {contacts}; } }
Po prostu tworzymy tablicę kontaktów i zwracamy je. Każdy kontakt powinien mieć identyfikator.
Na koniec musimy po prostu zaimportować InMemoryWebApiModule
do pliku app.module.ts
i udostępnić naszą fałszywą usługę zaplecza.
import { InMemoryWebApiModule } from “angular-in-memory-web-api”; import { BackendService } from “./backend.service”; /* ... */ @NgModule({ declarations: [ /*...*/ ], imports: [ /*...*/ InMemoryWebApiModule.forRoot(BackendService) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Następnie utwórz ContactService
, który zawiera kod do pracy z kontaktami:
$ ng gs contact
Otwórz plik src/app/contact.service.ts
i zaktualizuj go, aby wyglądał podobnie do następującego kodu:
import { Injectable } from '@angular/core'; import { HttpClient } from “@angular/common/http”; @Injectable({ providedIn: 'root' }) export class ContactService { API_URL: string = "/api/"; constructor(private http: HttpClient) { } getContacts(){ return this.http.get(this.API_URL + 'contacts') } getContact(contactId){ return this.http.get(`${this.API_URL + 'contacts'}/${contactId}`) } }
Dodaliśmy dwie metody:
-
getContacts()
Za zdobycie wszystkich kontaktów. -
getContact()
Aby uzyskać kontakt przez id.
Możesz ustawić API_URL
na dowolny adres URL, ponieważ nie będziemy używać prawdziwego zaplecza. Wszystkie żądania zostaną przechwycone i wysłane do zaplecza w pamięci.
Tworzenie naszych komponentów kątowych
Zanim zobaczymy, jak korzystać z różnych funkcji routera, stwórzmy najpierw kilka komponentów w naszym projekcie.
Udaj się do terminala i uruchom następujące polecenia:
$ ng gc contact-list $ ng gc contact-detail
Spowoduje to wygenerowanie dwóch komponentów ContactListComponent
i ContactDetailComponent
i dodanie ich do głównego modułu aplikacji.
Konfigurowanie routingu
W większości przypadków będziesz używać Angular CLI do tworzenia projektów z konfiguracją routingu, ale w tym przypadku dodamy go ręcznie, abyśmy mogli lepiej zrozumieć, jak działa routing w Angularze.
Dodawanie modułu routingu
Musimy dodać AppRoutingModule
, który będzie zawierał trasy naszych aplikacji i wyjście routera, w którym Angular wstawi aktualnie dopasowany komponent w zależności od bieżącego adresu URL przeglądarki.
Zobaczymy:
- Jak stworzyć moduł Angular do routingu i zaimportować go;
- Jak dodawać trasy do różnych komponentów;
- Jak dodać gniazdo routera.
Najpierw zacznijmy od utworzenia modułu routingu w pliku app-routing.module.ts
. Wewnątrz src/app
utwórz plik za pomocą:
$ cd angular7-router-demo/src/app $ touch app-routing.module.ts
Otwórz plik i dodaj następujący kod:
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = []; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
Zaczynamy od zaimportowania NgModule
z pakietu @angular/core
, który jest dekoratorem TypeScript używanym do tworzenia modułu Angular.
Importujemy również klasy RouterModule
i Routes
z pakietu @angular/router
. RouterModule
udostępnia metody statyczne, takie jak RouterModule.forRoot()
, służące do przekazywania obiektu konfiguracyjnego do routera.
Następnie definiujemy stałą tablicę routes
typu Routes
, która będzie używana do przechowywania informacji dla każdej trasy.
Na koniec tworzymy i eksportujemy moduł o nazwie AppRoutingModule
(możesz go nazwać, jak chcesz), który jest po prostu klasą TypeScript ozdobioną dekoratorem @NgModule
, który pobiera obiekt metainformacji. W atrybucie imports
tego obiektu wywołujemy statyczną RouterModule.forRoot(routes)
z tablicą routes jako parametrem. W tablicy exports
dodajemy RouterModule
.
Importowanie modułu routingu
Następnie musimy zaimportować ten routing modułów do głównego modułu aplikacji, który znajduje się w pliku src/app/app.module.ts
:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Importujemy AppRoutingModule
z ./app-routing.module
i dodajemy go w tablicy imports
modułu głównego.
Dodawanie gniazda routera
Na koniec musimy dodać gniazdo routera. Otwórz plik src/app/app.component.html
, który zawiera główny szablon aplikacji i dodaj komponent <router-outlet>
:
<router-outlet></router-outlet>
W tym miejscu router Angular wyrenderuje komponent odpowiadający ścieżce bieżącej przeglądarki.
To wszystkie kroki, które musimy wykonać, aby ręcznie skonfigurować routing w projekcie Angular.
Tworzenie tras
Teraz dodajmy trasy do naszych dwóch komponentów. Otwórz plik src/app/app-routing.module.ts
i dodaj następujące routes
do tablicy route:
const routes: Routes = [ {path: 'contacts' , component: ContactListComponent}, {path: 'contact/:id' , component: ContactDetailComponent} ];
Pamiętaj, aby zaimportować dwa komponenty do modułu routingu:
import { ContactListComponent } from './contact-list/contact-list.component'; import { ContactDetailComponent } from './contact-detail/contact-detail.component';
Teraz możemy uzyskać dostęp do dwóch komponentów ze ścieżek /contacts
i contact/:id
.
Dodawanie łączy nawigacyjnych
Następnie dodajmy łącza nawigacyjne do naszego szablonu aplikacji za pomocą dyrektywy routerLink
. Otwórz src/app/app.component.html
i dodaj następujący kod w górnej części gniazda routera:
<h2><a [routerLink] = "'/contacts'">Contacts</a></h2>
Następnie musimy wyświetlić listę kontaktów w ContactListComponent
. Otwórz src/app/contact-list.component.ts
a następnie dodaj następujący kod:
import { Component, OnInit } from '@angular/core'; import { ContactService } from '../contact.service'; @Component({ selector: 'app-contact-list', templateUrl: './contact-list.component.html', styleUrls: ['./contact-list.component.css'] }) export class ContactListComponent implements OnInit { contacts: any[] = []; constructor(private contactService: ContactService) { } ngOnInit() { this.contactService.getContacts().subscribe((data : any[])=>{ console.log(data); this.contacts = data; }) } }
Tworzymy tablicę contacts
do przechowywania kontaktów. Następnie wstrzykujemy ContactService
i wywołujemy metodę getContacts()
instancji (w zdarzeniu cyklu życia ngOnInit
), aby pobrać kontakty i przypisać je do tablicy contacts
.
Następnie otwórz plik src/app/contact-list/contact-list.component.html
i dodaj:
<table> <tr> <th>Name</th> <th>Email</th> <th>Actions</th> </tr> <tr *ngFor="let contact of contacts" > <td>{{ contact.name }}</td> <td>{{ contact.email }}</td> <td> <a [routerLink]="['/contact', contact.id]">Go to details</a> </td> </tr> </table>
Przeglądamy kontakty i wyświetlamy nazwę i adres e-mail każdego kontaktu. Tworzymy również łącze do komponentu szczegółów każdego kontaktu za pomocą dyrektywy routerLink
.
To jest zrzut ekranu komponentu:
Kiedy klikniemy link Przejdź do szczegółów , przeniesie nas do ContactDetailsComponent
. Trasa ma parametr id
, zobaczmy, jak możemy uzyskać do niej dostęp z naszego komponentu.
Otwórz plik src/app/contact-detail/contact-detail.component.ts
i zmień kod, aby wyglądał podobnie do następującego kodu:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ContactService } from '../contact.service'; @Component({ selector: 'app-contact-detail', templateUrl: './contact-detail.component.html', styleUrls: ['./contact-detail.component.css'] }) export class ContactDetailComponent implements OnInit { contact: any; constructor(private contactService: ContactService, private route: ActivatedRoute) { } ngOnInit() { this.route.paramMap.subscribe(params => { console.log(params.get('id')) this.contactService.getContact(params.get('id')).subscribe(c =>{ console.log(c); this.contact = c; }) }); } }
Wstawiamy ContactService
i ActivatedRoute
do komponentu. W zdarzeniu cyklu życia ngOnInit()
pobieramy parametr id , który zostanie przekazany z trasy i używamy go do uzyskania szczegółów kontaktu, które przypisujemy do obiektu contact
.
Otwórz plik src/app/contact-detail/contact-detail.component.html
i dodaj:
<h1> Contact # {{contact.id}}</h1> <p> Name: {{contact.name}} </p> <p> Email: {{contact.email}} </p>
Kiedy pierwszy raz odwiedzamy naszą aplikację z 127.0.0.1:4200/
, outlet nie renderuje żadnego komponentu, więc przekierujmy pustą ścieżkę do ścieżki contacts
, dodając następującą trasę do tablicy route:
{path: '', pathMatch: 'full', redirectTo: 'contacts'}
Chcemy dopasować dokładnie pustą ścieżkę, dlatego określamy strategię pełnego dopasowania.
Wniosek
W tym samouczku zobaczyliśmy, jak korzystać z routera Angular, aby dodać routing i nawigację do naszej aplikacji. Widzieliśmy różne koncepcje, takie jak gniazdko routera, trasy i ścieżki, i stworzyliśmy demonstrację, aby praktycznie pokazać różne koncepcje. Możesz uzyskać dostęp do kodu z tego repozytorium.