-
6장) Angular 2 -HeroEditor- (3)Angular 2017. 1. 10. 21:48
이어서 Hero Editor 를 계속 만들어 봅시다.
오늘은 Multiple Component 파트 입니다.
현재까지의 작업은 컴포넌트 하나에 모든 로직이 들어 가 있습니다. 이러다 나중애 앱이 커지게 되면
관리하기 정말 힘들겠죠?
그래서 이제 각각 컴포넌트로 나누는 작업이 필요합니다.
현재 만들어진 부분에서 먼저 Hero detail 부분을 떼어내서 컴포넌트로 만들어 봅시다.
/src/app/ 폴더내부에 hero-detail 폴더를 만들고 그 안에
hero-detail.component.ts 파일과 hero.detail.component.html 파일을
만듭시다.
그전에 잠깐 !! 설마 일일이 손으로 폴더 만들고, 파일만들고 하는 건 아니겠죠?
지금 우리가 쓰고 있는게 뭘까요 바로바로 angular-cli 입니다. 이놈의 기능은 단지 개발환경만 잡아주는게 아닙니다.
Component , Directive , Pipe , Service 등등 모두 커맨드 한방으로 짠 만들어 줍니다.
그럼 해볼까요?
cmd 창에서 현재 프로젝트 폴더로 갑니다.
그리고 ng g component hero-detail 명령어를 사용합시다.
그러면 놀라운 일이 ? 생깁니다.
/src/app/hero-detail 폴더를 만들고 내부에 ts , html , css 파일을 뚝딱 만들어 줍니다.
오오 편합니다.
/src/app/hero-detail/hero-detail.component.ts
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-hero-detail', templateUrl: './hero-detail.component.html', styleUrls: ['./hero-detail.component.css'] }) export class HeroDetailComponent implements OnInit { constructor() { } ngOnInit() { } }
파일을 보니 깔끔하게 초기화 되어있습니다.
저기서 OnInit 는 곧 배우게 되니 지금은 무시합시다.
이제 Template 파일도 떼어내야 합니다. 이전 app.component.html 파일로 가서 detail 부분을 가져옵시다.
그리고 hero-detail.component.html 파일에 붙여넣기 해야겠죠?
/src/app/hero-detail/hero-detail.component.html
<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>
자 여기서 달라진 점이 있습니다.
selectedHero 부분이 그냥 hero 로 바뀌었습니다.
당연히 바뀌어야 될 부분이겠죠. 컴포넌트를 떼어냈으니 현재 hero-detail 에서는 selectedHero 라는 변수를
더 이상 사용하지 않습니다. hero-detail 에서는 hero 라는 새로운 변수를 사용할 예정이기에
selectedHero 는 hero 로 이름을 바꿨습니다.
자 이제 hero-detail.component.ts 에 hero : Hero 라는 변수를 주면 될까요? 안됩니다.
Hero 라는 모델은 app.component.ts 파일에 정의되어있습니다.
이놈을 hero-detail 에서 사용하기 위해서는 해당 모델을 import 해야 됩니다.
그럼 hero-detail 컴포넌트에서 import { Hero } from '../app.component' 코드로 불러오면 될까요? 됩니다.
다만 이는 우리들이 원하는 디자인 패턴이 아닙니다.
Component , Model , Service 의 구분을 명확하게 하기 위해 Hero 라는 새로운 모델파일을 만들고
나머지 컴포넌트가 공동으로 이를 가져다 쓰도록 합시다.
그러기 위해 /src/app/ 폴더에 hero.ts 파일을 만들고 app.component.ts 파일에서 Hero 클래스를 가져와서
붙여넣기 합시다.
/src/app/Hero.ts
export class Hero { id: number; name: string; }
심플하게 모델파일이 완성되었습니다.
이제 이놈을 쓰기 위해 app.component.ts 파일상단에 import { Hero } from './hero' 코드를 넣어줍시다.
추가로 hero-detail.component.ts 파일 상단에도 import { Hero } from '../hero' 코드를 넣어줍시다.
이제 다시 hero-detail 을 봅시다.
해당 hero-detail 에 선택된 영웅을 가져와서 보여주기 위해 app.component 에서 selectedHero 를 가져와야 합니다.
그럼 이놈을 hero-detail 에 어떻게 넘겨 줄 것이냐?
먼저 app.component.html 파일로 가서 코드를 추가합니다.
/src/app/app.component.html
<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> <app-hero-detail [hero]="selectedHero"></app-hero-detail>
hero-detail 의 selector 인 app-hero-detail 태그가 추가 되었습니다.
이렇게 되면 해당 부분에 hero-detail 컴포넌트가 나타나게 됩니다.
여기서 [hero]="selectedHero" 라는 부분이 있는데 이 부분이 바로 자식 컴포넌트에게 부모가 데이터를
바인딩 하는 부분입니다. 자식 컴포넌트의 hero 라는 변수에 selectedHero 를 대입한다는 것 입니다.
추가로 설명하면 저번 장에서 [] 부분은 속성값을 지정할때 사용한다고 했습니다.
그럼 답이 나왔네요. app-hero-detail 즉 hero-detail 컴포넌트의 속성=변수 hero 라는 놈을 찾아서
그놈한테 selectedHero 를 준다 라는게 성립합니다.
자 이제 이렇게만 하면 끝일까요? 아닙니다.
이제 hero-detail 컴포넌트에서 hero 라는 변수는 부모에게서 입력받는 변수라는 걸 설정해줘야 합니다.
그러기 위해 hero-detail.component.ts 파일을 수정합시다.
/src/app/hero-detail/hero-detail.component.ts
import { Component, OnInit, Input } from '@angular/core'; import { Hero } from '../hero'; @Component({ selector: 'app-hero-detail', templateUrl: './hero-detail.component.html', styleUrls: ['./hero-detail.component.css'] }) export class HeroDetailComponent implements OnInit { @Input() hero :Hero ; constructor() { } ngOnInit() { } }
추가된 부분은 import 부분에서 Input 을 새롭게 import 하였고
내부 로직클래스에서 @Input() 추가 되었습니다. @Input 이 바로 해당 변수는 입력받는 변수라는 걸
알려주는 역활을 합니다.
이제 제대로 작동하는지 봐야겠죠?
잠깐 ! angular 에서 component 를 추가 하고 , 컴포넌트 간의 의존성을 유지하기 위해서는
연결을 시켜줘야 합니다.
한마디로 app.component 에 hero-detail 을 import 시켜줘야 app.component 에서
해당 컴포넌트를 인식하고 사용한다는 것 입니다.
그럼 app.component 파일 상단에 hero-detail 컴포넌트를 import 시켜줘야 할까요?
예전 angular 2 에서는 그래야 했지만 angular 가 버전업을 거듭하면서 더욱 편리하게
변했습니다. app.module 파일에서 이 모든 것을 관리 할 수 있게 되었습니다.
그래서 app.module.ts 파일에서 hero-detail 컴포넌트를 추가 시켜주면 다른 어떤 컴포넌트에서도
hero-detail 컴포넌트를 사용할 수 있습니다.
자 app.module.ts 파일로 가봅시다.
그런데 가보면 깜짝 놀랄일이 생겼습니다.
/src/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 { AppComponent } from './app.component'; import { HeroDetailComponent } from './hero-detail/hero-detail.component'; @NgModule({ declarations: [ AppComponent, HeroDetailComponent ], imports: [ BrowserModule, FormsModule, HttpModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
나는 추가하지도 않았는데 벌써 hero-detail 을 import 하고
declarations 에 추가도 되어있습니다. 누구의 짓일까요? 바로 angular-cli 의 짓(?) 입니다.
cli 명령어로 생성할 시 자동으로 app.module 파일에 추가를 시켜줍니다. 오오 정말 편합니다.
이제 감탄은 끝내고 app 이 제대로 작동하는지 확인 해봅시다.
제대로 작동하는군요.
이번 장은 여기서 끝입니다. 구글신 님 다음은 뭔가요?
이 다음 챕터는 Services 부분 입니다. 벌써부터 궁금하고 두근거리네요(?).
이제 Hero Editor 는 3챕터 밖에 안남았습니다.
후딱 끝내고 새로운 놈을 만들어 봅시다.
'Angular' 카테고리의 다른 글
8장) Angular 2 -HeroEditor- (5-1) (2) 2017.01.14 7장) Angular 2 -HeroEditor- (4) (5) 2017.01.12 5장) Angular 2 -HeroEditor- (2) (7) 2017.01.08 4장) Angular 2 -HeroEditor- (1) (1) 2017.01.05 3장) Angular 2 프로젝트 폴더구조 살펴보기 (7) 2017.01.03