ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 8장) Angular 2 -HeroEditor- (5-1)
    Angular 2017. 1. 14. 22:21


    이제 Hero Editor 도 얼마 남지 않았습니다.  

    오늘은 Router 에 대하여 알아봅니다. 

     router 는 내용이 많아서 부득이하게 2개로 나눴습니다. 


    Hero Editor 에 새로운 기능을 추가 하려 합니다. 

    대시보드를 만들어 영웅들의 순위를 나타내고, 해당 영웅을 클릭하면 상세보기로 이동 하도록 하려 합니다.

    그러기 위해서 Angular Router 를 추가해서 대시보드와 영웅목록 , 상세정보를 Router 를 이용하여 

    이동하도록 만들겁니다. 


    오늘의 계획은 이렇습니다. 

    - AppComponent 는 이제 Root Component 의 기능을 확고히 하며, 해당 컴포넌트는 Router에 맞춰서 나타나는

      컴포넌트를 보여주는 컴포넌트가 될 것 입니다.

    - AppComponent 의 Heroes 를 별도의 컴포넌트로 분리합니다.

    - 라우팅을 추가합니다.

    - 대쉬보드 컴포넌트를 추가합니다.

    - 대쉬보드 컴포넌트를 라우터에 추가합니다. 


    자 먼저 현재 AppComponent 영웅의 목록을 바로 나타냅니다. 

    대쉬보드를 추가하고 영웅목록과 대쉬보드를 이동할 수 있도록 만들려면 일단 

    AppComponen 는 탐색처리만 해야 합니다. 

    AppComponent 의 Heroes 즉, 영웅목록을 보여주는 코드를 HeroesComponent 를 만들어 

    옮깁시다. 

    커맨드 창에서 ng g component heroes 명령어를 사용하여 컴포넌트를 만듭니다.

    만들어 졌다면 현재 AppComponent 내부의 코드를 모두 복사하여 HeroesComponent 로 옮기고 

    selector , template , styles , class 의 이름을 변경합니다. 

    (angular-cli 명령어로 만들었기 때문에 자동으로 ngModule 에 heroesComponent 가 추가 됩니다.)


    app/heroes/heroes.component.ts 

    
    import { Component , OnInit} from '@angular/core';
    import { Hero } from '../hero';
    import { HeroService } from '../hero.service';
    
    
    
    @Component({
      selector: 'app-heroes',
      templateUrl: './heroes.component.html',
      styleUrls: ['./heroes.component.css']
    })
    export class HeroesComponent implements OnInit{
       constructor(private heroservice : HeroService){}
    
       title = 'Tour of Heroes'; 
       heroes : Hero[];
       selectedHero: Hero; 
       onSelect(hero:Hero) : void { 
         this.selectedHero = hero; 
      }
    
      ngOnInit() : void {
         this.heroservice.getHeroes()
         .then(result => this.heroes = result);
      }
    }
    

    바뀐 부분은 import 부분의 Hero 와 HeroService 를 불러오는 경로가 바뀌었습니다. 

    현재 폴더가 app/heroes 로 변했기 때문에 ../ 으로 변경되었습니다. 

    selector 와 templateUrl , styleUrls 그리고 class 의 이름이 변경되었습니다. 

    그리고 app.component.html , app.component.css 내용도 복사해서 

    heroes.component.html , heroes.component.css 로 옮깁니다. 



    자 이제 영웅목록을 보여주는 컴포넌트는 따로 떼어놓았습니다. 

    이제 AppComponent 를 변경할 차례입니다.  


    app/app.component.ts 

    
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
       title = 'Tour of Heroes'; 
    }
    


    app/app.component.html 

    
    <h1>{{title}}></h1>
    <app-heroes></app-heroes>
    


    app.component 를 새롭게 정의 하였습니다. 

    app.component.html 파일은 타이틀과 새롭게 만든 heroesComponent 의 selector 를 지정하고 있습니다.

    자 일단 실행시켜보면 이전과 달라진 건 없습니다. 다만 영웅목록을 새로운 컴포넌트로 분리 시켰습니다. 

    이제 라우터를 추가 시켜야 합니다. 

    가장 먼저 할 일은 indrx.html 파일에 <base href="/"> 를 head 태그 안에 추가 하는 겁니다. 

    헌데 angular-cli 가 이미 추가해 두었네요. 넘나 편한것 

    하지만 여기서 질문이 나와야 됩니다. base href 는 뭘하는 놈이고 값을 왜 "/" 로 주었는지 ? 

    angular-router 는 페이지 탐색을 위해 pushState 를 사용합니다.  

    이 pushState 는 html5 에서 지원되는 history 객체의 새로운 함수 입니다. 

    SPA 에서 화면전환 없이 URL을 변경하고 데이터를 주고 받는데 사용합니다.  이 부분에 대해서는 따로 

    글을 적어 두겠습니다. 

    그리고 base href 는 Url 변경시 "/"를 앞에 붙여주게 됩니다. 

    일단 한번 Router 를 적용시켜 봅시다. 

    먼저 Router 경로를 지정해 주기 위해 app.module.ts 파일에 router 를 추가 해 줍니다. 


    app/app.module.ts 

    
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { HttpModule } from '@angular/http';
    import { RouterModule } from '@angular/router';
    
    import { AppComponent } from './app.component';
    import { HeroDetailComponent } from './hero-detail/hero-detail.component';
    import { HeroService } from './hero.service';
    import { HeroesComponent } from './heroes/heroes.component';
    
    
    @NgModule({
      declarations: [
        AppComponent,
        HeroDetailComponent,
        HeroesComponent
      ],
      imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        RouterModule.forRoot([
          {
            path : 'heroes',
            component : HeroesComponent
          }
        ])
      ],
      providers: [
        HeroService
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    


    Router Module 를 import 시키고 RouterModule 을 imports 에 추가 시켰습니다. 

    여기서 forRoot 는 경로 탐색을 Root 경로 중심으로 탐색한다는 뜻 입니다. 

    path 는 url 경로 이름이고 component 는 나타낼 컴포넌트 입니다. 

    현재 HeroesComponent 를 지정해 주었습니다. 

    이젠 브라우저 주소에 /heroes 를 입력하면 HeroesComponent 를 나타내야 합니다. 

    하지만 어디서 나타나야 할까요 ? 우리는 아직 어디서 나타낼지를 정해주지 않았습니다. 


    그래서 appComponent 에 해당 주소로 가는 a 태그와 해당 경로의 컴포넌트를 보여주는 

    <router-outlet> 태그를 추가 할 것 입니다. 


    app/app.componrnt.html

    
    <h1>{{title}}</h1>
    <a routerLink="/heroes">Heroes</a>
    <router-outlet></router-outlet>
    


    여기서 router-link 태그는 탐색할 라우터 경로를 지정하는 것 입니다. 

    <router-outlet> 라우터에서 지정된 컴포넌트를 보여주는 역활을 합니다. 

    이제 저장하고 ng-serve 명령어로 실행 한뒤 확인 해봅시다. 


    첫 메인화면에서는 타이틀과 Heroes 태그만 보이고 해당 태그를 클릭하면 영웅목록 화면이 나타납니다. 

    그리고 Url 주소뒤에 /heroes 가 붙어있는 것을 볼 수 있습니다. 

    거기다 화면전환이 없었지만 뒤로가기가 작동하는 것 역시 볼 수 있습니다. 


    라우터에 첫번째 경로를 만들었습니다. 

    이제 여기서 대쉬보드 컴포넌트를 추가 할 것 입니다. 

    먼저 dashboard 컴포넌트를 만들기 위해 ng g component dashboard 를 명령어를 실행합시다.

    그리고 dashboard.component.html 파일에 <h3>My DashBoard</h3> 를 추가합니다. 

    이제 라우터에 연결시켜 볼까요? 


    app/app.module.ts

    
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    import { HttpModule } from '@angular/http';
    import { RouterModule } from '@angular/router';
    
    import { AppComponent } from './app.component';
    import { HeroDetailComponent } from './hero-detail/hero-detail.component';
    import { HeroService } from './hero.service';
    import { HeroesComponent } from './heroes/heroes.component';
    import { DashboardComponent } from './dashboard/dashboard.component';
    
    
    @NgModule({
      declarations: [
        AppComponent,
        HeroDetailComponent,
        HeroesComponent,
        DashboardComponent
      ],
      imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        RouterModule.forRoot([
          {
            path : 'heroes',
            component : HeroesComponent
          }, 
          {
            path : 'dashboard',
            component : DashboardComponent
          },
          {
            path:'',
            redirectTo : '/dashboard',
            pathMatch : 'full'
          }
        ])
      ],
      providers: [
        HeroService
      ],
      bootstrap: [AppComponent] 
    })
    export class AppModule { }
    


    새로운 경로가 2개 추가 되었습니다. 

    dashboard 경로가 추가되고, 처음 접속 하였을때 dashboard 화면이 나오게 하기 위해 

    '' 경로에는 redirectTo 로 '/dashboard' 를 지정해 주었습니다.

    이제 단순 http://localhost:4200 으로 들어갔을때는 /dashboard 로 자동으로 들어가게 됩니다. 

    그리고 app.component.html 파일에 dashboard 링크를 추가 합시다. 


    app/app.component.html 

    
    <h1>{{title}}</h1>
    <nav>
    <a routerLink="/heroes">Heroes</a>
    <a routerLink="/dashboard">Dashboard</a>
    </nav>
    <router-outlet></router-outlet>
    
    


    dashboard 태그를 추가 시켰고 , 여기에 nav 태그로 감쌌습니다. 

    nav 태그는 나중에 스타일을 지정할 때 필요하기에 미리 추가 시켰습니다. 

    이제 다시 실행하여 제대로 작동하는지 확인 해봅시다.

    링크도 제대로 작동하고 메인화면이 dashboard 로 잘 설정되었습니다. 

    이제 dashboard 에 4명의 영웅을 표시해봅시다. 

    먼저 dashboard.component.html 파일을 수정합니다. 


    app/dashboard/dashboard.component.html

    
    <h3>Top Heroes</h3>
    <div class="grid grid-pad">
      <div *ngFor="let hero of heroes" class="col-1-4">
        <div class="module hero">
          <h4>{{hero.name}}</h4>
        </div>
      </div>
    </div>
    
    


    살펴보면 이전에 배웠던 *ngFor 지시자를 사용하여 hero 의 이름을 표시하고 있습니다. 

    이제 dashboardComponent 에서 이를 설정해 줘야 겠죠.

    dashboardComponent  코드를 수정합시다. 


    app/dashboard/dashboard.component.ts

    
    import { Component, OnInit } from '@angular/core';
    import { Hero } from '../hero';
    import { HeroService } from '../hero.service';
    
    @Component({
      selector: 'app-dashboard',
      templateUrl: './dashboard.component.html',
      styleUrls: ['./dashboard.component.css']
    })
    export class DashboardComponent implements OnInit {
    
      heroes : Hero[];
    
    
      constructor(private heroservice : HeroService) { }
      
    
      ngOnInit() {
        this.heroservice.getHeroes() 
        .then(heroes => this.heroes = heroes.slice(1,5));
      }
    
    }
    
    


    Hero 와 HeroService 를 import 하고 heroes 배열에는 4명의 영웅만 나타내도록 slice 함수를 이용하였습니다. 

    이제 확인해 보겠습니다. 

    제대로 4명의 영웅들이 표시 됩니다. 

    이번장에서는 라우트의 설정을 진행했습니다. 

    다음 장에서는 해당 히어로의 이름을 클릭하면 HeroDetail 컴포넌트로 이동하도록 설정하고 

    rxjs 에 관련된 설명을 약간 추가하려 합니다. 

    끝 

     





    'Angular' 카테고리의 다른 글

    Angular 4 업데이트 변경점 정리  (1) 2017.03.26
    9장) Angular 2 -HeroEditor- (5-2)  (2) 2017.02.04
    7장) Angular 2 -HeroEditor- (4)  (5) 2017.01.12
    6장) Angular 2 -HeroEditor- (3)  (1) 2017.01.10
    5장) Angular 2 -HeroEditor- (2)  (7) 2017.01.08

    댓글