기술적으로 정확하지만 다른 답변은 Angular의 URL 대 경로 일치에 대한 설명에서 도움이 될 것입니다. 나는 pathMatch: full
당신이 라우터가 처음에 어떻게 작동하는지 모른다면 무엇을하는지 완전히 이해할 수 없다고 생각합니다 .
먼저 몇 가지 기본적인 사항을 정의하겠습니다. 이 URL을 예로 사용하겠습니다 /users/james/articles?from=134#section
..
분명 할 수도 있지만 먼저 쿼리 매개 변수 ( ?from=134
)와 조각 ( #section
)이 경로 일치에서 어떤 역할도하지 않는다는 점을 지적 해 보겠습니다 . 기본 URL ( /users/james/articles
) 만 중요합니다.
Angular는 URL을 세그먼트 로 분할합니다 . 의 세그먼트는 /users/james/articles
물론 users
, james
및 articles
입니다.
라우터 구성은 단일 루트 노드 가있는 트리 구조입니다. 각 Route
객체는 노드로, children
노드는 다른 children
노드 또는 리프 노드가 될 수 있습니다.
라우터의 목표 는 URL의 모든 (!!!) 세그먼트 와 정확히 일치하는 루트 노드에서 시작 하는 라우터 구성 분기 를 찾는 것 입니다. 이것은 매우 중요합니다! Angular가 전체 URL 과 일치 할 수있는 경로 구성 분기를 찾지 못하는 경우 - 더 이상도 그 이하도 - 아무것도 렌더링하지 않습니다 .
예를 들어 대상 URL이 /a/b/c
이지만 라우터가 /a/b
또는 중 하나만 일치 할 수있는 경우 일치 항목 /a/b/c/d
이 없으며 응용 프로그램은 아무것도 렌더링하지 않습니다.
마지막으로, 경로가있는 경로 는 일반 경로와 약간 다르게 redirectTo
동작하며 , 누구든지 정말로 사용하고 싶은 유일한 장소 인 것 같습니다.pathMatch: full
. 그러나 우리는 나중에 이것에 대해 설명 할 것입니다.
기본 ( prefix
) 경로 일치
이름 뒤에있는 이유 prefix
는 이러한 경로 구성이 구성된 항목 path
이 나머지 URL 세그먼트의 접두사 인지 확인하기 때문 입니다. 그러나 라우터는 전체 세그먼트 와 만 일치 할 수 있으므로이 이름을 약간 혼란스럽게 만듭니다.
어쨌든 이것이 우리의 루트 수준 라우터 구성이라고 가정 해 보겠습니다.
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,
},
],
},
],
},
];
Route
여기에 있는 모든 단일 개체는 기본 일치 전략 인 prefix
. 이 전략은 라우터가 전체 구성 트리를 반복 하고 URL이 완전히 일치 할 때까지 세그먼트별로 대상 URL 세그먼트 와 일치 시키려고 시도 함을 의미합니다 . 이 예에서 수행되는 방법은 다음과 같습니다.
- 첫 번째 URL 세그먼트와 정확히 일치하는 항목을 찾기 위해 루트 배열을 반복합니다
users
.
'products' !== 'users'
이므로 해당 분기를 건너 뜁니다. .startsWith()
또는 대신 동등성 검사를 사용하고 있습니다. .includes()
전체 세그먼트 일치 만 계산됩니다!
:other
모든 값과 일치하므로 일치합니다. 그러나 대상 URL이 아직 완전히 일치하지 않으므로 ( james
및 일치해야 함 articles
) 라우터가 자식을 찾습니다.
- 의 유일한 아이
:other
IS tricks
이다, !== 'james'
따라서, 일치하지.
- 그런 다음 Angular는 루트 배열로 되돌아 가서 거기에서 계속됩니다.
'user' !== 'users
, 분기를 건너 뜁니다.
'users' === 'users
-세그먼트가 일치합니다. 그러나 이것은 아직 완전 일치가 아니므로 자녀를 찾아야합니다 (3 단계와 동일).
'permissions' !== 'james'
, 넘겨.
:userID
무엇이든 일치하므로 james
세그먼트에 대한 일치가 있습니다 . 그러나 이것은 여전히 완전한 일치 가 아니므로 일치하는 자식을 찾아야합니다 articles
.
:userID
하위 경로가있는 것을 볼 수 있으며 articles
이는 전체 일치를 제공 합니다 ! 따라서 응용 프로그램은 UserArticlesComponent
.
전체 URL ( full
) 일치
예 1
이제 users
경로 구성 개체가 다음과 같다고 상상해보십시오 .
{
path: 'users',
component: UsersComponent,
pathMatch: 'full',
children: [
{
path: 'permissions',
component: UsersPermissionsComponent,
},
{
path: ':userID',
component: UserComponent,
children: [
{
path: 'comments',
component: UserCommentsComponent,
},
{
path: 'articles',
component: UserArticlesComponent,
},
],
},
],
}
의 사용법에 유의하십시오 pathMatch: full
. 이 경우 1-5 단계는 동일하지만 6 단계는 다릅니다.
'users' !== 'users/james/articles
-의 경로 구성 이 전체 URL 과 일치 하지 않으므로 세그먼트가 일치 하지 않습니다 .users
pathMatch: full
users/james/articles
- 일치하는 항목이 없으므로이 분기를 건너 뜁니다.
- 이 시점에서 일치하는 항목을 찾지 못한 채 라우터 구성의 끝에 도달했습니다. 응용 프로그램은 아무것도 렌더링 하지 않습니다 .
예 2
대신 이것을 가지고 있다면 어떨까요?
{
path: 'users/:userID',
component: UsersComponent,
pathMatch: 'full',
children: [
{
path: 'comments',
component: UserCommentsComponent,
},
{
path: 'articles',
component: UserArticlesComponent,
},
],
}
users/:userID
와 pathMatch: full
일치하는 경우에만 users/james
따라서는 다시 한 번 더-일치 없습니다, 응용 프로그램은 아무것도 렌더링하지 않습니다.
예제 3
이것을 고려해 봅시다 :
{
path: 'users',
children: [
{
path: 'permissions',
component: UsersPermissionsComponent,
},
{
path: ':userID',
component: UserComponent,
pathMatch: 'full',
children: [
{
path: 'comments',
component: UserCommentsComponent,
},
{
path: 'articles',
component: UserArticlesComponent,
},
],
},
],
}
이 경우 :
'users' === 'users
-세그먼트가 일치하지만 james/articles
여전히 일치하지 않습니다. 아이들을 찾아 보자.
'permissions' !== 'james'
- 건너 뛰기.
:userID'
하나의 세그먼트와 만 일치 할 수 있습니다 james
. 그러나 pathMatch: full
경로이며 일치해야합니다 james/articles
(나머지 전체 URL). 그렇게 할 수 없으므로 일치하지 않습니다 (따라서이 분기를 건너 뜁니다)!
- 다시 말하지만, 우리는 URL과 일치하는 것을 찾지 못했고 응용 프로그램은 아무것도 렌더링 하지 않습니다 .
아시다시피 pathMatch: full
구성은 기본적으로 다음과 같이 말합니다.
내 아이들을 무시하고 나만 일치시킵니다. 나머지 모든 URL 세그먼트를 직접 일치시킬 수없는 경우 계속 진행하십시오.
리디렉션
Route
를 정의한 모든 항목 redirectTo
은 동일한 원칙에 따라 대상 URL과 일치합니다. 여기서 유일한 차이점 은 세그먼트가 일치 하는 즉시 리디렉션이 적용 된다는 것 입니다. 즉, 리디렉션 경로가 기본 prefix
전략을 사용하는 경우 부분 일치만으로도 리디렉션이 발생할 수 있습니다 . 다음은 좋은 예입니다.
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,
},
],
},
];
초기 URL ( /users/james/articles
)의 경우 다음과 같은 결과가 발생합니다.
'not-found' !== 'users'
- 넘겨.
'users' === 'users'
-우리는 일치합니다.
- 이 경기는이
redirectTo: 'not-found'
되는, 즉시 적용을 .
- 대상 URL이로 변경됩니다
not-found
.
- 라우터는 다시 일치를 시작하고
not-found
즉시 일치하는 항목을 찾습니다 . 응용 프로그램은 NotFoundComponent
.
이제 users
경로에 다음과 같은 경우 어떤 일이 발생할지 고려하십시오 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'
- 넘겨.
users
URL의 첫 번째 세그먼트와 일치하지만 경로 구성에 full
일치 가 필요 하므로 건너 뜁니다.
'users/:userID'
일치 users/james
합니다. articles
여전히 일치하지 않지만이 경로에는 자식이 있습니다.
- 우리
articles
는 아이들에게 어울리는 것을 찾습니다 . 이제 전체 URL이 일치하고 응용 프로그램이 렌더링 UserArticlesComponent
됩니다.
빈 경로 ( path: ''
)
빈 경로는 "소비"하지 않고 모든 세그먼트 와 일치 할 수 있기 때문에 약간의 특별한 경우입니다 (따라서 자식은 해당 세그먼트를 다시 일치시켜야합니다). 이 예를 고려하십시오.
const routes: Routes = [
{
path: '',
children: [
{
path: 'users',
component: BadUsersComponent,
}
]
},
{
path: 'users',
component: GoodUsersComponent,
},
];
액세스를 시도한다고 가정 해 보겠습니다 /users
.
path: ''
항상 일치하므로 경로가 일치합니다. 그러나 전체 URL이 일치하지 않습니다. 여전히 일치해야합니다 users
!
users
나머지 (그리고 유일한!) 세그먼트와 일치 하는 child 가 있고 전체 일치가 있음을 알 수 있습니다. 응용 프로그램은 BadUsersComponent
.
이제 원래 질문으로 돌아가
OP는 다음 라우터 구성을 사용했습니다.
const routes: Routes = [
{
path: 'welcome',
component: WelcomeComponent,
},
{
path: '',
redirectTo: 'welcome',
pathMatch: 'full',
},
{
path: '**',
redirectTo: 'welcome',
pathMatch: 'full',
},
];
루트 URL ( /
)로 이동하는 경우 라우터가이를 해결하는 방법은 다음과 같습니다.
welcome
빈 세그먼트와 일치하지 않으므로 건너 뜁니다.
path: ''
빈 세그먼트와 일치합니다. 여기에는 pathMatch: 'full'
전체 URL (단일 빈 세그먼트가 있음)과 일치했기 때문에 만족 스럽습니다.
- 리디렉션이
welcome
발생하고 응용 프로그램이 렌더링 WelcomeComponent
됩니다.
없었다면 pathMatch: 'full'
?
실제로 모든 것이 똑같이 작동 할 것으로 기대합니다. 그러나 Angular는 이러한 구성 ( { path: '', redirectTo: 'welcome' }
)을 명시 적으로 방지 합니다. Route
위의 내용 을 입력하면 welcome
이론적으로 무한 리디렉션 루프가 생성 되기 때문 입니다. 따라서 Angular 는 오류를 던지기 때문에 응용 프로그램이 전혀 작동하지 않습니다! ( https://angular.io/api/router/Route#pathMatch )
실제로 Angular 는 이러한 끝없는 리디렉션에 대한 보호 기능을 구현 했기 때문에 이것은 나에게 너무 의미가 없습니다 . 라우팅 수준 당 단일 리디렉션 만 실행합니다! 이렇게하면 모든 추가 리디렉션이 중지됩니다 (아래 예에서 볼 수 있음).
어때 path: '**'
?
path: '**'
.가 포함 되거나 포함되지 않은 모든 항목 ( af/frewf/321532152/fsa
일치)과 절대적 으로 일치합니다 pathMatch: 'full'
.
또한 모든 것과 일치하기 때문에 루트 경로도 포함 { path: '', redirectTo: 'welcome' }
되어이 설정에서 완전히 중복됩니다.
재미있게도 다음과 같은 구성을 사용하는 것이 좋습니다.
const routes: Routes = [
{
path: '**',
redirectTo: 'welcome'
},
{
path: 'welcome',
component: WelcomeComponent,
},
];
우리가 이동하는 경우 /welcome
, path: '**'
일치 및 일어날에 오신 것을 환영합니다 리디렉션됩니다. 이론적으로 이것은 리디렉션의 끝없는 루프를 시작해야하지만 Angular는 (앞에서 언급 한 보호 기능 때문에) 즉시 중지하고 모든 것이 잘 작동합니다.