이번엔 라우트 안의 라우트를 알아볼것이다.
위 그림에서 App Root Component는 Feature A, B, C를 가지며 Feature A는 A1, A2, A3을 가진다.
여기서 A1, A2, A3이 바로 차일드 라우트에 해당한다.
다음 코드는 앵귤러가이드문서의 예이다.
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { CrisisCenterHomeComponent } from './crisis-center-home.component'; import { CrisisListComponent } from './crisis-list.component'; import { CrisisCenterComponent } from './crisis-center.component'; import { CrisisDetailComponent } from './crisis-detail.component'; const crisisCenterRoutes: Routes = [ { path: 'crisis-center', component: CrisisCenterComponent, children: [ { path: '', component: CrisisListComponent, children: [ { path: ':id', component: CrisisDetailComponent }, { path: '', component: CrisisCenterHomeComponent } ] } ] } ]; @NgModule({ imports: [ RouterModule.forChild(crisisCenterRoutes) ], exports: [ RouterModule ] }) export class CrisisCenterRoutingModule { }
Feature에 해당하는게 CrisisCenter이고 그 안에 CrisisCenterComponent가 Feature의 루트콤포넌트이고 CrisisListComponent, CrisisDetailComponent, CrisisCenterHomeComponent가 있다.
RouterModule.forChild메서드를 사용한것을 눈여겨 보아야 한다. forRoot가 아니다.
이렇게 정의한 모듈은 AppModule즉 루트모듈에 추가해준다. 이 때 앞선 포스트에서도 언급한데로 import순서가 url pattern matching 의 순서와 동일하다는것에 유의해야 한다.
상대적인 네비게이션
crisis center feature를 빌드후 detail component를 보려면 /로 시작하는 절대 주소로 접근하게 된다.
라우터는 라우트설정의 맨 위에서부터 절대주소를 매칭한다.
절대경로를 통해서 Crisis center feature에 접근이 가능하지만 상위라우팅구조에 링크가 고정된다. 만일 상위 경로(/crisis-center)를 변경하게 되면 링크파라메터를 반드시 변경해주어야 한다.
this.router.navigate(['/hero', hero.id]); // 이런코드가 존재한다면 '/hero'부분을 수정해주어야 한다는 의미로 보임.
이는 현재 URL segment에 상대경로를 정의함으로써 디펜던시로부터 자유로울수 있다. feature영역내에서의 네비게이션은 상위 라우트경로에 상관없이 유지될수 있다.
./ 또는 /가 없이 시작하면 현재 레벨을 의미
../ 는 한단게 상위 레벨을 의미
Router.navigate 메서드로 상대경로로 이동하려면 어떤 라우트트리에 있는지에 대한 정보가 필요하기 때문에 ActivatedRoute를 제공해야 한다.
링크파라메터배열을 링크한 후에 relativeTo속성에 ActivatedRoute를 셋해준다. 그러면 라우터는 현재 액티브된 라우트위치에 기반하여 URL을 계산해낸다.
항상 절대주소를 사용하려면 navigateByUrl메서드를 사용하면 된다.
다음은 Crisis detail을 상대주소로 접근하는 예이다.
src/app/crisis-center/crisis-list.component.ts constructor( private service: CrisisService, private route: ActivatedRoute, private router: Router ) {} onSelect(crisis: Crisis) { this.selectedId = crisis.id; // Navigate with relative link this.router.navigate([crisis.id], { relativeTo: this.route }); }
Router서비스가 아니고 RouterLink를 사용하게 된다면 동일한 링크파라메터를 사용한다. relativeTo속성이 보이지 않는데 이는 RouterLink가 내장하고 있다.
template: `
<ul class="items">
<li *ngfor="let crisis of crises | async">
<a [routerlink]="[crisis.id]" [class.selected]="isSelected(crisis)">
<span class="badge">{{ crisis.id }}</span>
{{ crisis.name }}
</a>
</li>
</ul>`
CrisisDetailComponent에서 뒤로가기를 하여 다시 리스트로 가고자 한다면 상대경로 이동으로 아래와 같이 시도할 수 있다.
src/app/crisis-center/crisis-detail.component.ts (relative navigation) // Relative navigation back to the crises this.router.navigate(['../', { id: crisisId, foo: 'foo' }], { relativeTo: this.route });