Tutaj używa pathmatch jako pełnego, a kiedy usuwam to pathmatch, nawet nie ładuje aplikacji ani nie uruchamia projektu
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { WelcomeComponent } from './home/welcome.component';
/* Feature Modules */
import { ProductModule } from './products/product.module';
@NgModule({
imports: [
BrowserModule,
HttpModule,
RouterModule.forRoot([
{ path: 'welcome', component: WelcomeComponent },
{ path: '', redirectTo: 'welcome', pathMatch: 'full' },
{ path: '**', redirectTo: 'welcome', pathMatch: 'full' }
]),
ProductModule
],
declarations: [
AppComponent,
WelcomeComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
angular
typescript
angular-router
Chanaka Amarasinghe
źródło
źródło
Ref: https://angular.io/guide/router#set-up-redirects
pathMatch: 'full'
oznacza, że cała ścieżka URL musi pasować i jest wykorzystywana przez algorytm dopasowywania tras.pathMatch: 'prefix'
oznacza, że wybierana jest pierwsza trasa, w której ścieżka jest zgodna z początkiem adresu URL, ale następnie algorytm dopasowywania tras kontynuuje wyszukiwanie pasujących tras podrzędnych, w których pasuje reszta adresu URL.źródło
Chociaż technicznie poprawne, inne odpowiedzi skorzystałyby na wyjaśnieniu dopasowania adresu URL do trasy w Angular. Nie sądzę, że możesz w pełni (przepraszam za kalambur) zrozumieć, co się
pathMatch: full
dzieje, jeśli nie wiesz, jak działa router.Najpierw zdefiniujmy kilka podstawowych rzeczy. Użyjemy tego adresu jako przykład:
/users/james/articles?from=134#section
.Może to być oczywiste, ale najpierw zwróćmy uwagę, że parametry zapytania (
?from=134
) i fragmenty (#section
) nie odgrywają żadnej roli w dopasowywaniu ścieżek ./users/james/articles
Liczy się tylko podstawowy adres URL ( ).Angular dzieli adresy URL na segmenty . Segmenty
/users/james/articles
są, oczywiścieusers
,james
iarticles
.Konfiguracja routera to struktura drzewiasta z jednym węzłem głównym. Każdy
Route
obiekt jest węzłem, który może miećchildren
węzły, które z kolei mogą mieć innechildren
lub być węzłami-liśćmi.Celem routera jest znalezienie gałęzi konfiguracji routera , zaczynającej się od węzła głównego, która pasowałaby dokładnie do wszystkich (!!!) segmentów adresu URL. To jest kluczowe! Jeśli Angular nie znajdzie gałęzi konfiguracji trasy, która pasowałaby do całego adresu URL - ni mniej, ni więcej - niczego nie wyrenderuje .
Np. Jeśli docelowy adres URL to,
/a/b/c
ale router jest w stanie dopasować tylko jedno/a/b
lub drugie/a/b/c/d
, wtedy nie ma dopasowania i aplikacja niczego nie wyrenderuje.Wreszcie trasy
redirectTo
zachowują się nieco inaczej niż zwykłe trasy i wydaje mi się, że byłyby jedynym miejscem, z którego naprawdę ktoś chciałby skorzystaćpathMatch: full
. Ale do tego dojdziemy później.prefix
Dopasowanie domyślnej ( ) ścieżkiPowodem tej nazwy
prefix
jest to, że taka konfiguracja trasy sprawdzi, czy skonfigurowanapath
jest prefiksem pozostałych segmentów adresu URL. Jednak router jest w stanie dopasować tylko pełne segmenty , co sprawia, że to nazewnictwo jest nieco mylące.W każdym razie, powiedzmy, że to jest nasza konfiguracja routera na poziomie głównym:
const routes: Routes = [ { path: 'products', children: [ { path: ':productID', component: ProductComponent, }, ], }, { path: ':other', children: [ { path: 'tricks', component: TricksComponent, }, ], }, { path: 'user', component: UsersonComponent, }, { path: 'users', children: [ { path: 'permissions', component: UsersPermissionsComponent, }, { path: ':userID', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ], }, ];
Zauważ, że każdy pojedynczy
Route
obiekt używa tutaj domyślnej strategii dopasowywania, czyliprefix
. Ta strategia oznacza, że router dokonuje iteracji po całym drzewie konfiguracji i próbuje dopasować go do docelowego adresu URL segment po segmencie, aż adres URL zostanie w pełni dopasowany . Oto, jak można by to zrobić w tym przykładzie:users
.'products' !== 'users'
, więc pomiń tę gałąź. Zauważ, że używamy sprawdzania równości, a nie.startsWith()
lub.includes()
- liczą się tylko dopasowania pełnego segmentu!:other
pasuje do dowolnej wartości, więc jest zgodna. Jednak docelowy adres URL nie jest jeszcze w pełni dopasowany (nadal musimy dopasowaćjames
iarticles
), dlatego router szuka dzieci.:other
jesttricks
, które jest!== 'james'
, więc nie pasuje.'user' !== 'users
, pomiń gałąź.'users' === 'users
- segment pasuje. Jednak nie jest to jeszcze pełne dopasowanie, dlatego musimy szukać dzieci (tak samo jak w kroku 3).'permissions' !== 'james'
, pomiń to.:userID
pasuje do wszystkiego, więc mamy dopasowanie dojames
segmentu. Jednak nadal nie jest to pełne dopasowanie, dlatego musimy szukać dziecka, które by pasowałoarticles
.:userID
ma trasę podrzędnąarticles
, która daje nam pełne dopasowanie! W ten sposób aplikacja renderujeUserArticlesComponent
.Pełne
full
dopasowanie adresu URL ( )Przykład 1
Wyobraź sobie teraz, że
users
obiekt konfiguracyjny trasy wyglądał następująco:{ path: 'users', component: UsersComponent, pathMatch: 'full', children: [ { path: 'permissions', component: UsersPermissionsComponent, }, { path: ':userID', component: UserComponent, children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ], }
Zwróć uwagę na użycie
pathMatch: full
. Gdyby tak było, kroki 1-5 byłyby takie same, jednak krok 6 byłby inny:'users' !== 'users/james/articles
- segment nie pasuje, ponieważ konfiguracja ścieżkiusers
zpathMatch: full
nie pasuje do pełnego adresu URL, czyliusers/james/articles
.Przykład 2
A co by było, gdybyśmy zamiast tego mieli to:
{ path: 'users/:userID', component: UsersComponent, pathMatch: 'full', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }
users/:userID
pathMatch: full
tylko z dopasowaniami wusers/james
ten sposób ponownie nie pasuje, a aplikacja nic nie wyświetla.Przykład 3
Rozważmy to:
{ path: 'users', children: [ { path: 'permissions', component: UsersPermissionsComponent, }, { path: ':userID', component: UserComponent, pathMatch: 'full', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ], }
W tym przypadku:
'users' === 'users
- segment pasuje, alejames/articles
nadal nie ma sobie równych. Poszukajmy dzieci.'permissions' !== 'james'
- pominąć.:userID'
może pasować tylko do jednego segmentujames
. Jest to jednakpathMatch: full
trasa i musi pasowaćjames/articles
(cały pozostały adres URL). Nie jest w stanie tego zrobić i dlatego nie pasuje (więc pomijamy tę gałąź)!Jak być może zauważyłeś,
pathMatch: full
konfiguracja zasadniczo mówi tak:Przekierowania
Każdy,
Route
który ma zdefiniowane a,redirectTo
zostanie dopasowany do docelowego adresu URL według tych samych zasad. Jedyna różnica polega na tym, że przekierowanie jest stosowane natychmiast po dopasowaniu segmentu . Oznacza to, że jeśli trasa przekierowująca używaprefix
strategii domyślnej , częściowe dopasowanie wystarczy, aby spowodować przekierowanie . Oto dobry przykład:const routes: Routes = [ { path: 'not-found', component: NotFoundComponent, }, { path: 'users', redirectTo: 'not-found', }, { path: 'users/:userID', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ];
/users/james/articles
Oto co by się stało w przypadku naszego początkowego adresu URL ( ):'not-found' !== 'users'
- pomiń to.'users' === 'users'
- mamy dopasowanie.redirectTo: 'not-found'
, które jest stosowane natychmiast .not-found
.not-found
od razu znajduje dopasowanie dla . Aplikacja renderuje sięNotFoundComponent
.Zastanów się teraz, co by się stało, gdyby
users
trasa miała równieżpathMatch: full
:const routes: Routes = [ { path: 'not-found', component: NotFoundComponent, }, { path: 'users', pathMatch: 'full', redirectTo: 'not-found', }, { path: 'users/:userID', children: [ { path: 'comments', component: UserCommentsComponent, }, { path: 'articles', component: UserArticlesComponent, }, ], }, ];
'not-found' !== 'users'
- pomiń to.users
będzie pasował do pierwszego segmentu adresu URL, ale konfiguracja trasy wymagafull
dopasowania, dlatego pomiń go.'users/:userID'
meczeusers/james
.articles
nadal nie jest dopasowany, ale ta trasa ma dzieci.articles
w dzieciach. Cały adres URL jest teraz dopasowany, a aplikacja renderuje sięUserArticlesComponent
.Pusta ścieżka (
path: ''
)Pusta ścieżka jest trochę szczególnym przypadkiem, ponieważ może dopasować dowolny segment bez „konsumowania” go (więc jego elementy podrzędne musiałyby ponownie dopasować ten segment). Rozważmy ten przykład:
const routes: Routes = [ { path: '', children: [ { path: 'users', component: BadUsersComponent, } ] }, { path: 'users', component: GoodUsersComponent, }, ];
Powiedzmy, że próbujemy uzyskać dostęp
/users
:path: ''
będzie zawsze pasować, więc trasa będzie pasować. Jednak cały adres URL nie został dopasowany - nadal musimy dopasowaćusers
!users
, które pasuje do pozostałego (i jedynego!) Segmentu i mamy pełne dopasowanie. Aplikacja renderuje sięBadUsersComponent
.Wróćmy teraz do pierwotnego pytania
OP użył tej konfiguracji routera:
const routes: Routes = [ { path: 'welcome', component: WelcomeComponent, }, { path: '', redirectTo: 'welcome', pathMatch: 'full', }, { path: '**', redirectTo: 'welcome', pathMatch: 'full', }, ];
Jeśli przechodzimy do głównego adresu URL (
/
), oto jak router mógłby to rozwiązać:welcome
nie pasuje do pustego segmentu, więc pomiń go.path: ''
pasuje do pustego segmentu. MapathMatch: 'full'
, co również jest zadowalające, ponieważ dopasowaliśmy cały adres URL (miał jeden pusty segment).welcome
dzieje i aplikacja się renderujeWelcomeComponent
.A jeśli nie było
pathMatch: 'full'
?Właściwie należałoby się spodziewać, że całość będzie się zachowywać dokładnie tak samo. Jednak Angular wyraźnie zapobiega takiej konfiguracji (
{ path: '', redirectTo: 'welcome' }
), ponieważ jeśli umieścisz toRoute
powyżejwelcome
, teoretycznie utworzyłoby to nieskończoną pętlę przekierowań. Więc Angular po prostu zgłasza błąd , przez co aplikacja w ogóle nie działała! ( https://angular.io/api/router/Route#pathMatch )Właściwie, to nie ma zbyt wiele sensu do mnie, ponieważ kątowe także wdrożył ochronę przed takimi nieskończonych przekierowań - tylko biegnie pojedynczy przekierowanie za routing poziom! To zatrzymałoby wszystkie dalsze przekierowania (jak zobaczysz w poniższym przykładzie).
O co chodzi
path: '**'
?path: '**'
dopasuje absolutnie wszystko (af/frewf/321532152/fsa
jest dopasowaniem) z lub bezpathMatch: 'full'
.Ponadto, ponieważ pasuje do wszystkiego, dołączona jest również ścieżka główna, co czyni ją
{ path: '', redirectTo: 'welcome' }
całkowicie zbędną w tej konfiguracji.Co zabawne, taka konfiguracja jest całkowicie w porządku:
const routes: Routes = [ { path: '**', redirectTo: 'welcome' }, { path: 'welcome', component: WelcomeComponent, }, ];
Jeśli przejdziemy do
/welcome
,path: '**'
nastąpi dopasowanie i nastąpi przekierowanie na powitanie. Teoretycznie powinno to zapoczątkować niekończącą się pętlę przekierowań, ale Angular natychmiast to zatrzymuje (ze względu na ochronę, o której wspomniałem wcześniej) i całość działa dobrze.źródło
Ignore my children and only match me. If I am not able to match all of the remaining URL segments myself, then move on.
gdzie w przypadku pełnego dopasowania ścieżki sekcji przekierowania wspomniałeśWe find a match for articles in the children. The whole URL is now matched and the application renders UserArticlesComponent.
Z tego, co zrozumiałem, nie powinno pasować również w Reidrect?ignore my children
wyjaśnienie. Wątpię, jak to widzą programiści Angular, ale jest to jedna z zasadpathMatch: 'full'
. Więc w przykładzie przekierowania, do którego się odnosisz, zwróć uwagę, żepathMath: 'full'
jest stosowany do drugiej trasy (path: 'users'
), która z tego powodu nie pasuje. Pasująca trasa topath: 'users/:userID'
, która nie używapathMatch: 'full'
i działa jak zwykle. Więc najpierw pasuje,users/james
a potem szukamyarticles
w jego potomkach (po raz kolejny nie używapathMatch: 'full'
).Strategia dopasowywania ścieżek, jedna z opcji „prefiks” lub „pełna”. Domyślnie jest to „prefiks”.
Domyślnie router sprawdza elementy adresu URL od lewej strony, aby sprawdzić, czy adres URL pasuje do podanej ścieżki, i zatrzymuje się, gdy istnieje dopasowanie. Na przykład „/ team / 11 / user” pasuje do „team /: id”.
Strategia dopasowania ścieżki „pełna” dopasowuje do całego adresu URL. Należy to zrobić podczas przekierowywania tras z pustymi ścieżkami. W przeciwnym razie, ponieważ pusta ścieżka jest prefiksem dowolnego adresu URL, router zastosowałby przekierowanie nawet podczas nawigacji do miejsca docelowego przekierowania, tworząc nieskończoną pętlę.
Źródło: https://angular.io/api/router/Route#properties
źródło