티스토리 뷰

지난 Angular 2 포스팅에서는 Directive에 대해 간단히 알아봤습니다. 지난번까지 작성한 소스는 app.component에 모든것을 다 넣은 형태였습니다. Hero 인터페이스 선언과 Hero 리스트 배열, 그리고 AppComponent가 한곳에 있으니 자연히 가독성이 떨어집니다. 이것을 이제부터 하나하나 나눠보겠습니다.


이번에도 역시나 npm start와 함께 시작합니다.

가장 먼저 제일 쉬운 Hero 인터페이스를 밖으로 빼내어 보겠습니다. 새로 hero.ts를 생성하고, app.component.ts에 있던 Hero 인터페이스 정의 부분을 빼냅니다.
export class Hero {
  id: number;
  name: string;
}

위와 같이 별도 파일로 빼내면 import를 시켜줘야 app.component가 정상화 됩니다. app.component 최상단에 아래와 같이 import 해줍니다.
import {Hero} from "./hero";
     . 상대경로 ./hero 파일에 있는 export 했던 Hero를 가져온다라는 의미입니다. ts는 생략 가능합니다.

동일한 방법으로 Hero 리스트도 빼내봅시다.  app.component에서 아래 부분을 빼서 mock-heroes.ts 파일을 만들어서 넣어줍니다.
import {Hero} from "./hero";

export var HEROES: Hero[] = [
    { "id": 11, "name": "Mr. Nice" },
    { "id": 12, "name": "Narco" },
    { "id": 13, "name": "Bombasto" },
    { "id": 14, "name": "Celeritas" },
    { "id": 15, "name": "Magneta" },
    { "id": 16, "name": "RubberMan" },
    { "id": 17, "name": "Dynama" },
    { "id": 18, "name": "Dr IQ" },
    { "id": 19, "name": "Magma" },
    { "id": 20, "name": "Tornado" }
];
     . 여기서도 Hero 인터페이스를 사용하므로 Hero를 import 해줬습니다.
     . var HEROES에는 export를 붙여 다른 파일에서 import 할 수 있도록 했습니다.

그리고 app.component에서는 Hero와 같이 mock-heroes도 import 시켜줍시다.
import {HEROES} from "./mock-heroes";

이제 app.component에서 마음에 안드는건 template 코드와 styles 코드입니다. 이것도 마저 빼줍시다.
app.component.html 파일과 app.component.css 파일을 각각 만들어서 template 코드와 styles 코드를 복사/붙여넣기 해줍니다.
<h1>{{title}}</h1>
<h2>My Heroes</h2>
<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>
<div *ngIf="selectedHero">
    <h2>{{selectedHero.name}} details!</h2>
    <div><label>id: </label>{{selectedHero.id}}</div>
    <div>
        <label>name: </label>
        <input [(ngModel)]="selectedHero.name" placeholder="name"/>
    </div>
</div>
.selected {
    background-color: #CFD8DC !important;
    color: white;
}
.heroes {
    margin: 0 0 2em 0;
    list-style-type: none;
    padding: 0;
    width: 15em;
}
.heroes li {
    cursor: pointer;
    position: relative;
    left: 0;
    background-color: #EEE;
    margin: .5em;
    padding: .3em 0;
    height: 1.6em;
    border-radius: 4px;
}
.heroes li.selected:hover {
    background-color: #BBD8DC !important;
    color: white;
}
.heroes li:hover {
    color: #607D8B;
    background-color: #DDD;
    left: .1em;
}
.heroes .text {
    position: relative;
    top: -3px;
}
.heroes .badge {
    display: inline-block;
    font-size:10pt;
    color: white;
    padding: 0.8em 0.7em 0 0.7em;
    background-color: #607D8B;
    line-height: 1em;
    position: relative;
    left: -1px;
    top: -4px;
    height: 1.8em;
    margin-right: .8em;
    border-radius: 4px 0 0 4px;
}

 

html과 css 파일로 각각 만들었으면 app.component.ts에서 두 파일들을 아래와 같이 import 할 수 있습니다.
import { Component } from '@angular/core';
import {Hero} from "./hero";
import {HEROES} from "./mock-heroes";

@Component({
    selector: 'my-app',
    templateUrl: 'app/app.component.html',
    styleUrls: ['app/app.component.css']
})

export class AppComponent {
    title = 'Tour of Heroes';
    heroes = HEROES;
    selectedHero: Hero;

    onSelect(hero: Hero) { this.selectedHero = hero; }
}
     . template 대신 templateUrl을 사용하여 html 파일을 import 합니다.
     . styles 대신 styleUrls를 사용하여 css 파일을 import 합니다. 여기서도 styles와 마찬가지로 string 배열을 사용해야 합니다.

이제 깔끔하게 파일이 나눠졌습니다. 원래 angular 홈페이지에서는 좀더 나중에 파일을 나누는데 저는 깔끔하게 해야 설명하기도 편하고 해서 미리 파일을 나눴습니다.

그럼 본격적으로 component를 나눠 보겠습니다. 지난번까지 만든 화면을 보면 위에는 리스트 화면, 아래는 선택한 Hero의 Detail 정보를 뿌려줍니다. 이 Detail 정보를 뿌려주는 것을 또 하나의 Component로 만들어 봅시다. 먼저 hero-detail.component.ts를 만듭니다.
import { Component } from '@angular/core';

@Component({
    selector: 'my-hero-detail',
    templateUrl: 'app/hero-detail.component.html'
})

export class HeroDetailComponent {
}
     . 지난번에 만든 app.component와 거의 동일합니다.
     . selector는 해당 Component를 사용할 때 html 코드에 입력될 태그명입니다.

그리고 위에 만든 Component에 template을 추가해줍니다.
<div *ngIf="hero">
    <h2>{{hero.name}} details!</h2>
    <div><label>id: </label>{{hero.id}}</div>
    <div>
        <label>name: </label>
        <input [(ngModel)]="hero.name" placeholder="name"/>
    </div>
</div>

이렇게 빼내고 보니 HeroDetailComponent에는 hero 변수가 없습니다. Angular 2에서는 하위 Component가 그냥 상위 Component의 변수를 같이 사용할 수 없습니다. 그래서 Input이라는 것에 대해서 알아봅니다. 상위 Component에서 하위 Component를 사용할때 Input 값으로 selectedHero를 넣어주게 되면 하위 Component가 정상적으로 동작할 수 있을 겁니다. 그래서 HeroDetailComponent를 아래와 같이 수정합니다.
import { Component, Input } from '@angular/core';
import {Hero} from "./hero";

@Component({
    selector: 'my-hero-detail',
    templateUrl: 'app/hero-detail.component.html'
})


export class HeroDetailComponent {
   @Input()
   hero: Hero;
}
     . Input 은 core Angular 라이브러리에 있습니다.
     . Input은 @Input() 과 같이 사용할 수 있습니다. (괄호 주의하세요.)

이러면 HeroDetailComponent는 Input값으로 Hero를 받을 수 있게 되었습니다. 그럼 AppComponent에서 HeroDetailComponent를 사용해볼까요? app.component.html 파일을 아래와 같이 수정해줍니다.
<h1>{{title}}</h1>
<h2>my heroes</h2>
<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>
<my-hero-detail [hero]="selectedhero"></my-hero-detail>
     . selector에서 선언한 명칭을 사용해서 기존의 템플릿을 삭제한 후, <my-hero-detail> 태그로 대체 했습니다.
     . Input 변수로 지정한 hero에 selectedHero를 Input 값으로 넣어줍니다.(문법은 [하위 Component Input 변수]="component 변수 값" 와 같이 작성하면 됩니다.)
     . 상위 Component에서 하위 Component로 값을 전달할때는 Input을 사용합니다.
이러면 될것 같지만 되지 않습니다. 마지막으로 AppComponent에 directives를 추가해줘야 정상적으로 하위 component를 사용할 수 있습니다.
import { Component } from '@angular/core';
import {Hero} from "./hero";
import {HEROES} from "./mock-heroes";
import {HeroDetailComponent} from "./hero-detail.component";

@Component({
    selector: 'my-app',
    templateUrl: 'app/app.component.html',
    styleUrls: ['app/app.component.css'],
    directives: [HeroDetailComponent]
})

export class AppComponent {
    title = 'Tour of Heroes';
    heroes = HEROES;
    selectedHero: Hero;

    onSelect(hero: Hero) { this.selectedHero = hero; }
}
     . directives에 Component를 넣어줍니다. 배열이며 Component 리스트를 넣어줍니다. (string이 아닙니다.)

이렇게 하면 지난 포스팅과 완전 똑같은 기능을 하지만 파일과 Component가 분리된 형태로 되었습니다. 기본적으로 Angular에서는 component base의 아키텍처를 권장합니다. component는 웹에서의 특정 조각조각이라고 보시면 됩니다. 조각들이 모여서 웹이되고요, 또 이러한 조각들은 이 페이지, 저 페이지에서 사용이 가능하도록 만듭니다. 그리고 화면과 로직을 분리함으로 인해서 개발자와 디자이너가 분리되어 작업을 할 수도 있습니다. 훨씬 깔끔해진 코드를 만족하며 이번 포스팅은 마치도록 하겠습니다. 역시 Angular 쪽이 공식홈페이지 것을 그대로 가져오니 포스팅이 스피디하네요. 즐코딩하세요^^

Angular 2 공식홈페이지 - tutorial - 3. Multiple Component : https://angular.io/docs/ts/latest/tutorial/toh-pt3.html

'Javascript > Angular' 카테고리의 다른 글

5-1. Routing 기초 - 1  (0) 2016.06.19
4. Service 만들기  (0) 2016.06.17
2. 기본적인 Directive 맛보기  (1) 2016.06.13
1. Data Binding 맛보기  (0) 2016.06.09
0. Angular 2 시작하기  (0) 2016.06.05
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함