Angular
をチュートリアルを使って勉強する機会があったので、その時の内容について説明していきます。
Angular
の本家サイトのチュートリアルの「 Master/Detail Components
」の説明をしていきたいと思います。
今までは Hero
コンポーネントだけで一覧の表示と編集を行なっていましたが、それを一覧のコンポーネント( Master
)と詳細のコンポーネント(Detail)に分割します。
このチュートリアルがマスターできれば、機能分割されたシンプルなコンポーネントの実装が行えるようになります。
本家サイトはこちらになります。
作成するプロジェクトは「 Tour of Heroes
」というアプリケーションです。
作成するアプリの概要についてはこちらから確認できます。
では、早速始めていきたいと思います!
開発環境
- macOS : Sierra 10.12.6
- node : 8.4.0
- npm : 5.3.0
- Angular : 4.3.6
HeroDetailComponent の作成
下記コマンドを実行して、 hero-detail
コンポーネントを作成します。
$ ng generate component hero-detail
コマンドを実行すると、 HeroDetailComponent
が生成され、 AppModule
にも宣言情報が追記されます。
テンプレート実装
詳細部分のテンプレートを実装します。
コンポーネントを追加した際に、 hero-detail.component.html
というファイルも追加されているので、そのファイルを編集していきます。
<div *ngIf="hero">
<h2>{{ hero.name | uppercase }} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label>name:
<input [(ngModel)]="hero.name" placeholder="name"/>
</label>
</div>
</div>
hero property を Input デコレータとして追加する
HeroDetailComponent
のテンプレートは Hero
という型のプロパティをバインドしています。 HeroDetailComponent
に Hero
というシンボルをインポートします。
import { Hero } from '../hero';
次に、今まで詳細部分のテンプレートの実装を行なっていた「 heroes.component.html
」の詳細表示を、 HeroDetailComponent
が実行されるように変更します。
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
hero-detail.component.ts
の @angular/core
のインポート文の所に Input
を追加します。
import { Component, OnInit, Input } from '@angular/core';
最後に @Input()
デコレータとして hero
プロパティを hero-detail.component.ts
に追加します。
export class HeroDetailComponent implements OnInit {
@Input() hero: Hero;
constructor() { }
ngOnInit() {
}
}
HeroDetailComponent を表示する
今のままではまだ詳細部分の表示はできないので、 HeroDetailComponent
が実行されるように、 HeroesComponent
周りを修正していきます。
HeroesComponent の修正
heroes.component.html
を修正します。
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
このように修正することで、 HeroDetail
をバインドするようになります。
heroes.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>
前回からの変更点
前回の1つのコンポーネントによる実装から2つのコンポーネントにしたことによる変更点は下記の通りです。
HeroesComponent
の影響範囲を小さくして、簡略化を行なった。HeroesComponent
を編集しなくてもHeroDetailComponent
を使って詳細部分のカスタマイズができるようになった。- 詳細部分を意識することなく、一覧のカスタマイズができるようになった。
- 機能を分割したことで詳細部分を再利用することができるようになった。
機能分割を行うことでそれぞれの機能が分離されるため、コード変更時の影響範囲を軽減させながら、機能拡張性を高めることができました!
ソースコードについて
今までのソースコードは Github
にあげてますので、詳細を確認したい方はこちらからソースコードを見てもらえればと思います。
最後に
今回のチュートリアルでコンポーネントの分割方法を理解することができました。コンポーネントを分割することで、作業分担も簡単になったり、コンポーネントの再利用性を高めることができるようになると思います。
また、コードのスパゲッティ化も防ぐこともできると思います。
ただ、あまりコンポーネントを分割しすぎても、管理やバインディングが煩雑になるので、どのサイズでコンポーネントを切り分けるかはプロジェクトの規模などに応じて決めていく必要があると思います。
コメント