前回の投稿Angluar2のクイックスタートとチュートリアルを実施 - その3の続きです。
前回作成したソースを使用します。
###本投稿の参照元(英語)
(バージョンが異なりますが、大きな影響はないと思います。)
Multiple Components - ts
###本章で学ぶこと
以下を学習します。
- 再使用可能なように、コンポーネントを分ける
- 入力(引数のような)を受け取るコンポーネントの作り方を学ぶ
-
NgModule
デコレータにdeclarations
配列を追加する - コンポーネント同士の親子バインドを学ぶ
###実行結果
本章を完了すると以下リンク先のようなものが出来上がります。
見た目は前回のアプリと変わっていません。
live-examples
事前準備
以下のコマンドによりサーバの起動を行います。プログラムの変更が即座にブラウザに反映されます。(サーバを落としていなければ不要です。)
cd angular2-tour-of-heroes
npm start
ヒーロー詳細コンポーネントの作成
前章まで、ヒーローの一覧とヒーローの詳細を同じコンポーネントにしていましたが、一つのファイルが大きくなりすぎると、メンテナンスの難度が上がります。
また、単一責任の原則(@gomi_ningenさんの記事)を犯しています。
ヒーロー詳細部分の分割
新たにファイル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
は以下の様になります。
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
に移し替えます。
export class Hero {
id: number;
name: string;
}
そして、app.component.ts
とhero-detail.component.ts
で、hero.ts
をインポートします。
import { Hero } from './hero';
HeroDetailComponent
は、HeroComponent
により表示されます。HeroComponent
ではユーザが選択したヒーローはselectedHero
プロパティに格納されます。
以下の様にAppComponent
のselectedHero
をHeroDetailComponent
のhero
プロパティにバインドします。
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
ここでのmy-hero-detail
は、HeroDetailComponent
の@Component
デコレータで定義したセレクター、hero
はHeroDetailComponent
のhero
プロパティです。
[バインド先]="バインド元"
の形で、プロパティの値を渡します。
詳細はこちら(英語)
hero
プロパティを入力にする方法は2つありますが、ここでは@Input
デコレータによる、アノテーションでそれを実現します。
HeroDetailComponent
クラスを以下の様に変更します。
export class HeroDetailComponent {
@Input()
hero: Hero;
}
@Input
デコレータの詳細はこちら(英語)
AppModuleの更新
AppModule
は、このアプリのメインモジュールです。このモジュールにHeroDetailComponent
を使用することを宣言します。
import { HeroDetailComponent } from './hero-detail.component';
つぎに@NgModule
デコレータのdeclarations
配列にHeroDetailComponent
を追加します。declarations
にはこのアプリで使用する全てのcomponent
, pipe
, directive
を定義します。
@NgModule({
imports: [
BrowserModule,
FormsModule
],
declarations: [
AppComponent,
HeroDetailComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
AppComponentの更新
アプリはHeroDetailComponent
を認識できるようになりました。AppComponent
のヒーロー詳細表示部分を削除し、以下の様に変更します。
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>
`,
これで、ヒーロー詳細の移行は完了です。
本章は以上です。次章ではサービスの作成方法を説明します。