1) Navigating to hero details
Hero-Detail 컴포넌트를 이용하여 dynamic-routing을 해봅시다.
일단 detail에 해당하는 URL로 이동하면 router-outlet 태그에는 Hero-detail 컴포넌트를 보여주는게 목적입니다.
그런데 문제점이 하나 있습니다.
바로 Hero-detail 컴포넌트가 Heroes 컴포넌트에 종속되어 있다는 겁니다.
기존에는,
- Heroes 컴포넌트 안에
selectedHero
라는 속성이 있음. - 각 영웅의 리스트를 클릭할 때 마다 event-handling을 통해서
selectedHero
의 값을 변화시킴 selectedHero
의 값을 Hero-detail 컴포넌트의hero
속성에 바인딩하여 그selectedHero
의 정보를 출력함.
의 논리로 작동했는데, 오늘은 3번부분만 약간 바꿔서
selectedHero
의 값을 받아서 이 값을 기준으로 특정 히어로에 대한 라우트로 이동한다.
로 바꾸면 됩니다.
1-1. 동적으로 라우트를 만들어서 연결하기
-
Detail 라우트를 만든다.
// app-routing.module.ts const routes: Routes = [ { path : 'heroes', component : HeroesComponent }, { path: 'dashboard', component: DashboardComponent }, { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, { path: 'detail/:id', component : HeroDetailComponent }, ];
:id
부분은id
라는 값에 따라서 동적으로 라우팅을 하겠다는 의미입니다. -
heroes 컴포넌트에다가
selectedHero
값에 대한 링크를 추가한다.<a routerLink="/detail/{{hero.id}}/"> <div>이름 : {{hero.name}}</div> <div>번호 : {{hero.id}}</div> </a>
주의! :
/detail/
와detail/
는 엄청난 차이가 있습니다.
아마 이제 이동은 될겁니다.. 다만, 데이터가 정상적으로 출력이 안됩니다.
왜냐하면 이 :id
값이 어떻게 Detail 컴포넌트에서 활용되는지를 명시하지 않았기 때문입니다.
1-2. id값을 컴포넌트에 적용하기
이제 /detail/11
이런식의 url
이 들어오면, 11이라는 아이디를 가진 hero의 정보를 표현해줘야 합니다.
방식은 다음과 같습니다.
-
/detail/11
과 같은 사용자가 입력한 주소를 얻는다.// hero-detail/hero-detail.component.ts import { ActivatedRoute } from '@angular/router';
ActivatedRoute
: 현재 활성화된 라우트에 대한 정보를 가지고 있는 클래스 -
그 주소에서
11
부분만 가져온다.// 먼저 라우트의 객체를 생성함. constructor( private route: ActivatedRoute, private heroService: HeroService, ) { }
// id부분만 가져오기 const id = +this.route.snapshot.paramMap.get('id');
route.snapshot
: 컴포넌트가 생성된 이후에 생기는 라우터의 정보를 담은 static file(image)paraMap
: 라우트의 파라미터 밸류와 값을 맵핑하는 딕셔너리(파이썬의 그 딕셔너리라고 생각하면 될듯합니다.)- 그런데 값이 항상 string 타입이기 때문에 +를 넣어줘서 형변환.
-
HeroService
를 통해서11
아이디를 가진 영웅을 찾아서 받아온다.-
HeroService
에 해당하는 아이디의 영웅을 가져오는 함수 만들기.// hero.service.ts getHero(id: number): Observable<Hero> { this.messageService.add(`${id}를 가진 영웅 FETCH 성공적`); const selectedHero = HEROES.find((hero) => (hero.id === id)); return of(selectedHero); }
-
Detail 컴포넌트에서
HeroService
의 함수를 이용하기.// hero-detail/hero-detail.component.ts ngOnInit() { this.getHero(); } getHero(): void { const id = +this.route.snapshot.paramMap.get('id'); this.heroService.getHero(id) .subscribe((hero) => { this.hero = hero; }); }
-
이제 성공적으로 데이터가 출력됩니다.
1-3. Find the way back
브라우저의 뒤로가기처럼 이전 url상태
를 기억하고 그 상태로 이동할 수 있는 뒤로가기버튼을 만들고 싶습니다.
-
뒤로가기 버튼 만들기
<button (click)="goBack()">뒤로가기</button>
-
goBack()
만들기일단
Location
이라는 클래스를 먼저 임포트해야합니다.Location
은 브라우저와 상호작용을 할 수 있는 Angular에서 제공하는 특별한 Service입니다.// hero-detail/hero-detail.component.ts import { Location } from '@angular/common'; constructor( private location: Location, ) { }
그리고, 버튼을 클릭시,
goBack()
이라는 함수가 실행되며 이전의url
로 이동하고 싶습니다.goBack(): void { this.location.back(); }
이
location.back()
함수를 통해서 브라우저의 history stack의 한 단계 이전으로 이동하는 것입니다.
두개의 뒤로가기 버튼은 정말 완벽하게 동일합니다.
뜬금없이 /detail/12
에서 /detail/11
로 이동한 다음에 뒤로가기버튼을 클릭해도
/detail/12
로 이동해줍니다.