Sanghyuk's Dev


저번 챕터에 이어서 Multiple Component 를 배워보겠습니다.

현재까지 작업들은 하나의 컴포넌트에 모든 로직이 들어가 있습니다.

차후 앱이 커진다면 관리하기가 힘들어집니다.

그래서 각각의 컴포넌트로 나누는 작업이 필요합니다.


현재 만들어진 부분에서 Hero detail 부분을 컴포넌트로 만들어보겠습니다.

/src/app/ 폴더 내부에 hero-detail 폴더를 만들고 그 안에

hero-detail.component.ts 파일과 hero-detail.component.html 파일을 만들겠습니다.


이런 작업을 angular-cli 를 이용하면 간단하게 만들 수 있습니다.

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 라는 새로운 변수를 사용할 예정이기 때문에 hero 로 이름을 바꿨습니다.

그렇다고 hero-detail.component.ts 에 hero : Hero 라는 변수를 주면 안됩니다.

Hero 라는 모델은 app.component.ts 파일에 정의되어있습니다.

이것을 hero-detail 에서 사용하기 위해서는 해당 모델을 import 해야 합니다.

Component, Model, Service 의 구분을 명확하게 하기 위해 Hero 라는 새로운 모델파일을 만들고

나머지 컴포넌트가 공동으로 가져다 쓸 수 있도록 만들겠습니다.

그러기 위해 /src/app/ 폴더에 hero.ts 파일을 만들고 app.component.ts 파일에서 Hero 클래스를 가져옵니다.


export class Hero{

  id: number;

  name: string;

}


/src/app/Hero.ts 라는 간단한 모델파일을 만들었습니다.


이 모델파일을 사용하기 위해 app.component.ts 파일 상단에 import { Hero } from './hero' 코드를 넣어야합니다.

추가로 hero-detail.component.ts 파일 상단에도 import { Hero } from '../hero' 를 넣어야합니다.


다시 hero-detail 을 보겠습니다.

해당 hero-detail 에 선택된 영웅을 가져와 보여주기 위해 app.component 에서 selectedHero 를 가져와야합니다.

먼저 /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 라는 변수는 부모에게서 입력받는 변수라는 걸 설정해줘야 합니다.

그러기 위해 /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 에서 버전업을 반복하면서 더욱 편리한 방법이 생겼습니다.

app.module 파일에서 이 모든 것을 관리할 수 있게 되었습니다.

그래서 app.module.ts 파일에서 hero-detail 컴포넌트를 추가 시켜주면 다른 컴포넌트에서도 hero-detail 컴포넌트를 사용할 수 있습니다.


/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 파일에 추가를 시켜줍니다.


이제 정상적으로 작동하는지 확인해보겠습니다.



정상적으로 작동하는 것을 볼 수 있습니다.

이번 챕터는 여기까지입니다.



REFERENCE

http://alexband.tistory.com/