이 게시물에는 코드작성이 포함되어 있습니다. 소스코드를 받으신 후 진행해 주세요. MEAN Stack/개발 환경 구축에서 설명된 프로그램들(git, npm, atom editor)이 있어야 아래의 명령어들을 실행할 수 있습니다.
이 게시물의 소스코드는 Tour of Heroes / MASTER/DETAIL(*ngFor, [class], (click), *ngIf)에서 이어집니다.
tour-of-heroes.git 을 clone 한 적이 있는 경우: 터미널에서 해당 폴더로 이동 후 아래 명령어들을 붙여넣기합니다. 폴더 내 모든 코드가 이 게시물의 코드로 교체됩니다. 이를 원치 않으시면 이 방법을 선택하지 마세요.
tour-of-heroes.git 을 clone 한 적이 없는 경우: 터미널에서 코드를 다운 받을 폴더로 이동한 후 아래 명령어들을 붙여넣기하여 tour-of-heroes.git 을 clone 합니다.
- Github에서 소스코드 보기: https://github.com/a-mean-blogger/tour-of-heroes/tree/0977d7b7dcc202340810fad4b7d8dd4dfbd0742e
Angular사이트의 공식 tutorial인 Tour of Heroes의 세번째 강의, Multiple Components입니다.
공식 tutorial link : https://angular.io/docs/ts/latest/tutorial/toh-pt3.html
온라인 예제 : https://angular.io/generated/live-examples/toh-pt3/eplnkr.html
지금까지는 웹사이트의 모든 class들을 app.component.ts에서 작성하였는데, 파일들 관리를 쉽게 하기 위해서 이 class들을 각자의 파일로 분리해 봅시다. 또한 @input
을 사용해 상위 component에서 component로 값을 전달하는 방법을 알아 봅시다.
이전 포스팅과 비교해서 기능상의 차이는 없습니다.
HeroDetailComponent class 와 Hero class를 app.component.ts에서 분리하여 새로운 파일로 만들어진 모습입니다.
새로 생성된 파일부터 살펴봅시다.
// src/app/hero.ts export class Hero { id: number; name: string; }
Hero class는 단순히 Hero의 타입을 담고 있는 class입니다. 이전과 비교해서 달라진 부분은 없습니다.export
를 사용해서 다른 파일에서 불러오기(import
)가 가능하다는 것만 보시고 다음 파일로 넘어갑시다.
// src/app/hero-detail.component.ts import { Component, Input } from '@angular/core'; //3 import { Hero } from './hero'; //1 @Component({ selector: 'hero-detail', //2-1 template: ` //2-2 <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> ` }) export class HeroDetailComponent { @Input() hero: Hero; //3 }
이전에 <div *ngIf="selectedHero">
부분을 때어내서 새로운 component 를 만들었습니다. 우선 눈여겨 봐야할 부분은 이 파일의 이름인데, Angular의 파일명 작성 약속(convention)을 따른 것입니다. 파일명 작성 약속은 다음과 같습니다.
.
으로 나타냄.-
를 사용하여 구분위 규칙을 모두 따른 결과 hero-detail.component.ts라는 파일 이름이 나오게 된 것입니다.
이제 코드를 살펴봅시다.
1. Hero 타입을 사용하기 위해 hero.ts에서 Hero class를 호출하고 있습니다.
2-1. selector
로 hero-detail
가 사용되었으므로 <hero-detail></hero-detail>
를 html에 삽입하면 이 component를 호출할 수 있다는 것을 알 수 있습니다.
2-2. template
에는 원래 있던 selectedHero가 사라지고 hero로 바뀐 것을 제외하면 변화된 부분은 없습니다.
3. 오늘 강의의 가장 중요한 부분인 @input
입니다. component간에 값을 전달할 수 있게 해주는 decorator인데요, input decorator(@input
)가 붙은 class의 항목은 html에서 해당 component를 호출할때 값을 전달 받을 수 있습니다. <selector_이름 [input_항목_이름]="값"></selector_이름>
의 형태로 호출하면 input_항목_이름에 값이 전달됩니다.
// src/app/app.component.ts import { Component } from '@angular/core'; import { Hero } from './hero'; //1 const HEROES: Hero[] = [ //... ]; @Component({ selector: 'my-app', template: ` //2 <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> <hero-detail [hero]="selectedHero"></hero-detail> `, styles: [` //... `] }) export class AppComponent { //... }
// ...
로 표시된 부부은 전과 비교해서 변화가 없는 부분입니다.
1. Hero 타입을 사용하기 위해 hero.ts에서 Hero class를 호출하고 있습니다.
2. 이 template의 마지막 부분 <hero-detail [hero]="selectedHero"></hero-detail>
을 살펴봅시다.
hero-detail은 HeroDetailComponent의 selector입니다. 이를 사용해서 html에 HeroDetailComponent를 호출하고, HeroDetailComponent의 hero에 selectedHero를 전달하고 있습니다. 이처럼 값을 전달할때는 []
를 사용합니다. 전달받은 selectedHero는 HeroDetailComponent에서 hero로 간주됩니다.
마지막으로 app.module을 살펴봅시다.
// src/app/app.module.ts import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { HeroDetailComponent } from './hero-detail.component'; //1 @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, HeroDetailComponent //1 ], bootstrap: [ AppComponent ] }) export class AppModule { }
1. Angular의 모든 component들은 @NgModule
의 declarations
에 등록되어야 사용할 수 있습니다. HeroDetailComponent 역시 import되고 등록되어야만 html에서 selector(hero-detail)를 통해 호출될 수 있습니다. 참고로 hero.ts의 Hero 클라스는 component가 아니라 타입을 정의하고 있는 단순 class이기 때문에 등록될 필요가 없습니다.
<selector_이름 [항목]=전달할_값></selector_이름>
로 값을 전달합니다.
댓글
이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기