반응형


영웅 상세 탐색

HeroDetailsComponent는 선택된 영웅의 상세를 표시한다. 지금 바로 HeroDetailsComponent는 HeroesComponent의 바닥에 단지 보이기만한다.

The user should be able to get to these details in three ways.

  1. 대시보드에 영웅을 클릭 함으로써
  2. 영웅들의 목록중에 영웅을 클릭함으로써
  3. 브라우저에 주소창에  영웅을 찾아서 표시하기위한  "deep link" URL을  붙힘으로써

이번 섹션에서는, 네이게이션을 HeroDetailsComponent로 활성화 할수 있고 그것을 HeroesComponent로부터 해방시키다.


HeroesComponent에서 영웅 상세를 삭제

HeroesComponent에 영웅 아이템을 클릭했을때, 앱은 HeroDetailComponent을 찾을것이며,  영웅들의 목록 뷰와 함깨 영웅 상세 뷰를 제자리로 되돌리것. 그것이 지금하는것처럼 영우 목록 뷰는 더이상 영웅 상세를 보여주지  않을것이다.

HeroesComponent 템플릿을 열고 바닥으로부터 <app-hero-detail> 요소를 삭제한다.

영웅 아이템을 클릭하는하면 지금 아무것도 하지 않는다. HeroDetailComponent로 라우팅을 활성화 한후에 얼마안되어 고칠것이다.


영웅 상세 라우트 추가

URL은 ~/detail/11 와 같은  영웅의 어떤 id 가 11의 영웅 상세 뷰를 네비게이팅하기에 좋은 URL  일것이다.

AppRoutingModule 을 열고 HeroDetailComponent 를 추가한다.


src/app/app-routing.module.ts (import HeroDetailComponent)

import { HeroDetailComponent }  from './hero-detail/hero-detail.component';

 경로 패턴이 영웅 상세뷰와 매치된 AppRoutingModule.routes 배열로 파라메터화된 라우트를 추가한다.

{ path: 'detail/:id', component: HeroDetailComponent },

경로안의 콜론 (:) 은  :id는 특정 영웅  id를 위한  플레이스홀더로  나타낸다.

이쯤에서, 모든 애플리케이션 라우터들은 제자리에 준비가 되었다.

src/app/app-routing.module.ts (all routes)

const routes: Routes = [

  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },

  { path: 'dashboard', component: DashboardComponent },

  { path: 'detail/:id', component: HeroDetailComponent },

  { path: 'heroes', component: HeroesComponent }

];


DashboardComponent 영웅 링크들

DashboardComponent 영웅 링크는 바로지금 아무것도 안한다.

이제 라우터는 HeroDetailComponent에 라우트를 가졌으므로, 대시보드에 영웅 링크 수정하여 매개변수화된 대시보드 라우트를 통해 탐색한다.


src/app/dashboard/dashboard.component.html (hero links)

<a *ngFor="let hero of heroes" class="col-1-4"  routerLink="/detail/{{hero.id}}">

앵귤라가 써넣은 바인딩을 *ngFor 반복자와 함깨 각각의 라우터링트 안에 반복되는 현 hero.id를 사용한다.


HeroesComponent 영웅 링크

HeroesComponent안에 영웅 아이템들은  클릭 이벤트는 꼭 컴포넌트의 onSelect() 메소드를 묶은  <li>요소 이다.

src/app/heroes/heroes.component.html (list with onSelect)

<ul class="heroes">

  <li *ngFor="let hero of heroes"

    [class.selected]="hero === selectedHero"

    (click)="onSelect(hero)">

    <span class="badge">{{hero.id}}</span> {{hero.name}}

  </li>

</ul>

<li> 뒤에 *ngFor의 옷을 벗는다. (<a>) 앵커 요소 안에 이름과 badge를 감싸고, 그리고 routerLink 속성을 대시보드 템플릿안에 같은 앵커에  추가한다.

src/app/heroes/heroes.component.html (list with links)

<ul class="heroes">

  <li *ngFor="let hero of heroes">

    <a routerLink="/detail/{{hero.id}}">

      <span class="badge">{{hero.id}}</span> {{hero.name}}

    </a>

  </li>

</ul>

프라이베이트한 스타일시트를 고쳐야만 한다.


죽은 코드 제거 (옵션)

HeroesComponent 클래스가 아직도 작업하는 동안에, onSelect() 메소드와 selectedHero 속성은 이미 사용되지 않는다.

이것은 멋지게 치웠고, 나중에 너자신에게 고마워 할 것이다. 죽은 코드를 잘라낸 후에 클래스다.

src/app/heroes/heroes.component.ts (cleaned up)

export class HeroesComponent implements OnInit {

  heroes: Hero[];


  constructor(private heroService: HeroService) { }


  ngOnInit() {

    this.getHeroes();

  }


  getHeroes(): void {

    this.heroService.getHeroes()

    .subscribe(heroes => this.heroes = heroes);

  }

}

Routable HeroDetailComponent

이전에 부모 HeroesComponent는  HeroDetailComponent.hero 속성과 영웅을 표싷는 HeroDetailComponent를 설정 됬다.

HeroesComponent 더이상 하지 못한다. 라우터는   ~/detail/11과 같은 URL에 응답 으로  HeroDetailComponent를 만든다.

HeroDetailComponent는 영웅을 표시하는 새로운 방법을 필요로합니다.

  • 라우터는 생성된 그것을 얻는다.
  • 라우트에서 id를 뽑아낸다.
  • 서버를 통해 HeroService로  id로 영웅을 습득하다.

다음의 import를 추가한다.

src/app/hero-detail/hero-detail.component.ts

import { ActivatedRoute } from '@angular/router';

import { Location } from '@angular/common';


import { HeroService }  from '../hero.service';

ActivatedRoute, HeroService, 그리고 생성자에 들어가는 지역 서비스 주입, 그것들의 값들을 프라이페이트 항목안에 저장한다.

constructor(

  private route: ActivatedRoute,

  private heroService: HeroService,

  private location: Location

) {}

ActivatedRoute 라우터가 HeroDetailComponent의 인스턴스에 대한 정보를 잡고 있다. 이콤포넌트는 라우터의 URL에서 추출한 파라메터를 담은 자루에 흥미를 가지고 있다. "id" 파라메터는 화면에 표시하는 영웅의 id이다.

HeroService는 원격서버로 부터 영웅 데이터를 받고 이 콤포넌트는 영우을 화면에 표시하는것을 얻는것을 사용할 것이다.

경로는 앵귤라 서비스가 브라우저와 함깨 소통하는것이다. 나중에  그 뷰로 뒤로 돌아가는것을 탐색할려면 사용할수 있다.


라우터 파라메터에서  id를 추출

ngOnInit()에서  라이프사이클 훅은 getHero() 호출하고 다음처럼 정의한다.

ngOnInit(): void {

  this.getHero();

}

getHero(): void {

  const id = +this.route.snapshot.paramMap.get('id');

  this.heroService.getHero(id)

    .subscribe(hero => this.hero = hero);

}


route.snapshot은 라우터 정보의 정적인 이미지를 금새 컴포넌트는 생성된다.

paramMap은 URL에 라우트 파라메터 값의 확장된 사전이다. "id" 키는 가지고온 영웅의 id 리턴한다.

라우트 파라메터는 항상 문자열이다. 자바스크립트 (+) 연산자는  영웅의 id가 될것이 문자열을 숫자로 전환킨다.

브라우저가 재생되고 컴파일러 에러와 함께 앱이 기능을 멈춘다. HeroService getHero() 메소드를 가지는것을 하지않는다. 이것을 지금 추가한다.


HeroService.getHero() 추가

HeroService 열고 getHero() 메소드를 추가한다.


src/app/hero.service.ts (getHero)

getHero(id: number): Observable<Hero> {

  // Todo: send the message _after_ fetching the hero

  this.messageService.add(`HeroService: fetched hero id=${id}`);

  return of(HEROES.find(hero => hero.id === id));

}

backticks ( ` ) 기호는   자바스크립트 템플릿이 내장되는 id를 문자그대로를 정의한다.

getHeroes(), getHero() 동기적 특색을 갖는다. RxJS of() 함수를 사용하여 Observable한 가짜 영웅을 리턴 한다.

실제 Http 요청 처럼 HeroDetailComponent를 변경하는것 없이 그것을 부를수 있게  getHero()를 재구현하는게 가능하다.


시도해 보자.

브라우저는 새로고침되고 앱이 다시 동작한다. 대시보드 혹은 영웅 목록에 있는 영웅을 클릭할수 있고 영웅의 상세 뷰를 네비게이트 한다.

브라우저 주소창에 localhost:4200/detail/11를 붙혀넣으면 , 라우터는 id가 11, "Mr. Nice"인 영웅의 상세뷰를 네비게이트 한다.


돌아오는 길 찾기

브라우저의 뒤로가기 버튼을 클릭함으로써 , 영웅 목록이나 대시 보드 뷰로 뒤로 갈수 있다. 당신에게 어떤 상세뷰를 보내느냐에 따라 달려있다.

HeroDetail 뷰에 그렇게 하는 버튼을 갖는것은 멋져질수 있다.

컴포넌트 템플릿에 바닥에 뒤로가기 버튼을 추가하고 컴포넌트의 goBack()메소드를 바인딩 합니다.

src/app/hero-detail/hero-detail.component.html (back button)

<button (click)="goBack()">go back</button>

미리 주입한 지역 서비스를 사용해서 브라우저 히스토리 스텍의 한단계 뒤로 찾아가는   콤포넌트 클래스에 goBack() 메소드를 추가한다.

src/app/hero-detail/hero-detail.component.ts (goBack)

goBack(): void {

  this.location.back();

}

브라우저를 새로 고치고 클릭하십시오. 사용자는 대시 보드에서 영웅 세부 정보로 돌아가 영웅 목록에서 세부 정보, 영웅 세부 정보 및 영웅 정보를 다시 볼 수 있습니다.

이페이지에서 추진하는 모든 자격요건 충족했다.


마지막 코드리뷰

https://angular.io/tutorial/toh-pt5#final-code-review 참조


요약

  • 다른 콤포넌트사이를 찾아가는 Angular 라우터를  추가된다.
  • AppComponent를 <a> 링크와 <router-outlet>이있는 탐색 쉘로 변환했습니다.
  • AppRoutingModule에서 라우터를 구성했습니다.
  • 간단한 경로, 리디렉션 경로 및 매개 변수화 된 경로를 정의했습니다.
  • anchor 요소에서 routerLink 지시문을 사용했습니다.
  • 밀접하게 결합 된 마스터 / 상세 뷰를 라우팅 된 상세 뷰로 리팩토링했습니다.
  • 라우터 링크 매개 변수를 사용하여 사용자가 선택한 영웅의 상세보기로 이동했습니다.
  • 여러 구성 요소간에 HeroService를 공유했습니다.


반응형

+ Recent posts