Angluar2のクイックスタートとチュートリアルを実施 - その4

前回の投稿[Angluar2のクイックスタートとチュートリアルを実施 - その3](http://qiita.com/gambare/items/a9fd17999b9192e99cd7)の続きです。
前回作成したソースを使用します。

###本投稿の参照元(英語)

(バージョンが異なりますが、大きな影響はないと思います。)
[Multiple Components - ts](https://angular.io/docs/ts/latest/tutorial/toh-pt3.html)


###本章で学ぶこと

以下を学習します。

 - 再使用可能なように、コンポーネントを分ける
 - 入力(引数のような)を受け取るコンポーネントの作り方を学ぶ
 - `NgModule`デコレータに`declarations`配列を追加する
 - コンポーネント同士の親子バインドを学ぶ


###実行結果

本章を完了すると以下リンク先のようなものが出来上がります。
見た目は前回のアプリと変わっていません。
[live-examples](https://angular.io/resources/live-examples/toh-3/ts/plnkr.html)

### 事前準備

以下のコマンドによりサーバの起動を行います。プログラムの変更が即座にブラウザに反映されます。(サーバを落としていなければ不要です。)

```bash
cd angular2-tour-of-heroes
npm start
```

# ヒーロー詳細コンポーネントの作成

前章まで、ヒーローの一覧とヒーローの詳細を同じコンポーネントにしていましたが、一つのファイルが大きくなりすぎると、メンテナンスの難度が上がります。
また、[単一責任の原則](http://qiita.com/gomi_ningen/items/02c42e2487d035f9c3c8)(@gomi_ningenさんの記事)を犯しています。

## ヒーロー詳細部分の分割
新たにファイル`app/hero-detail.component.ts`を作成して、そこにヒーローの詳細を移します。

```ts:app/hero-detail.component.ts

import { Component, Input } from '@angular/core';

@Component({
  selector: 'my-hero-detail',
})
export class HeroDetailComponent {
}
```

`@angular/core`の`Component`と`Input`をインポートします。`@Component`デコレータで、この部品の要素名`my-hero-detail`を指定します。`Input`はあと説明します。
また、後ほど`app/app.component.ts`でこのファイルを使用します。

## ヒーロー詳細テンプレート

現時点ではヒーローの一覧とヒーローの詳細が`AppComponent`内で同居しています。`AppComponent`のテンプレートから、ヒーローの詳細を表示する部分を切り取りし、`HeroDetailComponent`へ貼り付けましょう。`AppComponent`で`selectedHero`プロパティとしていた部分は`HeroDetailComponent`では`hero`プロパティとしてください。
結果`app/hero-detail.component.ts`の`template`は以下の様になります。

```html:app/hero-detail.component.ts
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`クラスを持たせる必要がありますが未定義です。`Hero`クラスは、`HeroComponent`に定義されています。まずは、`Hero`プロパティを`app/hero.ts`に移し替えます。

```ts:app/hero.ts
export class Hero {
  id: number;
  name: string;
}
```

そして、`app.component.ts`と`hero-detail.component.ts`で、`hero.ts`をインポートします。

```ts:
import { Hero } from './hero';
```

`HeroDetailComponent`は、`HeroComponent`により表示されます。`HeroComponent`ではユーザが選択したヒーローは`selectedHero`プロパティに格納されます。
以下の様に`AppComponent`の`selectedHero`を`HeroDetailComponent`の`hero`
プロパティにバインドします。

```html:app/app.component.tsのtemplate
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
```

ここでの`my-hero-detail`は、`HeroDetailComponent`の`@Component`デコレータで定義したセレクター、`hero`は`HeroDetailComponent`の`hero`プロパティです。
`[バインド先]="バインド元"`の形で、プロパティの値を渡します。

詳細は[こちら](https://angular.io/docs/ts/latest/guide/attribute-directives.html#why-input)(英語)

`hero`プロパティを入力にする方法は2つありますが、ここでは`@Input`デコレータによる、アノテーションでそれを実現します。
`HeroDetailComponent`クラスを以下の様に変更します。

```ts:app/hero-detail.component.tsのHeroDetailComponentクラス
export class HeroDetailComponent {
  @Input()
  hero: Hero;
}
```

`@Input`デコレータの詳細は[こちら](https://angular.io/docs/ts/latest/guide/attribute-directives.html#input)(英語)

# AppModuleの更新

`AppModule`は、このアプリのメインモジュールです。このモジュールに`HeroDetailComponent`を使用することを宣言します。

```ts:app/app.module.ts
import { HeroDetailComponent } from './hero-detail.component';
```

つぎに`@NgModule`デコレータの`declarations`配列に`HeroDetailComponent`を追加します。`declarations`にはこのアプリで使用する全ての`component`, `pipe`, `directive`を定義します。

```ts:app/app.module.tsの@NgModuleデコレータ
@NgModule({
  imports: [
    BrowserModule,
    FormsModule
  ],
  declarations: [
    AppComponent,
    HeroDetailComponent
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }
```

# AppComponentの更新

アプリは`HeroDetailComponent`を認識できるようになりました。`AppComponent`のヒーロー詳細表示部分を削除し、以下の様に変更します。

```html:app/app.component.tsのテンプレート
template: `
  <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>
`,
```

これで、ヒーロー詳細の移行は完了です。

-------
本章は以上です。[次章](http://qiita.com/gambare/items/fa1416cf2d2973cd270e)ではサービスの作成方法を説明します。