LoginSignup
0
1

More than 5 years have passed since last update.

0からのAngular④

Last updated at Posted at 2017-08-25

前回の続き
今回は、大きくなってしまったAppComponentをサブコンポーネントに分けて、コンポーネントの役割をきちんと分ける。

サブコンポーネントを定義

まずは、AppComponentのサブコンポーネントとなるHeroDetailComponent./src/app/hero-detail.component.tsを作成し、定義する。

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

@Component({
  selector: 'hero-detail',
})

export class HeroDetailComponent {

}

ここで、いくつかポイントがある。

  • コンポーネントを定義するためには、1行目のようにComponentシンボルをimportする
  • ~Componentとなるようにクラス名をつける
  • @ComponentのselectorはHTML上でのコンポーネントのタグ名になる
  • コンポーネントクラスは常にexportする

サブコンポーネントにテンプレートを用意

サブコンポーネントがビューに表示するテンプレートを用意する。
AppComponentから以下と同じ箇所をカットし、hero-detail.component.tsに移動する。

@Component({
  selector: 'hero-detail',
  template: `
    <div *ngIf="hero">
      <h2>{{selectedHero.name}} details!</h2>
      <div><label>id: </label>{{selectedHero.id}}</div>
      <div>
        <label>name: </label>
        <input [(ngModel)]="selectedHero.name" placeholder="name">
      </div>
    </div>
  `
})

このとき、*ngIf部分をselectedHeroからheroに変更する。
そうする理由は、サブコンポーネントでは、HeroDetailComponentクラスにheroを定義し、こちらにバインドさせるから。
ということで、HeroDetailComponentクラスにheroを定義する。

export class HeroDetailComponent {
  hero: Hero;
}

Heroクラスを切り出す。

hero-detail.component.tsでもHeroクラスを参照することになったので、Heroクラスがapp.component.tsに定義されたままだと不都合。
Heroクラスを./src/app/hero.tsというファイルを作成し、こちらに移動させる。

export class Hero {
  constructor(
    public id: number,
    public name: string,
    ) {  }
}

クラスを切り出したので、app.component.tsとhero-detail.component.tsでHeroクラスをimportする。

import { Hero } from './hero';

子コンポーネントに値を渡す

app.component.tsからhero-detail.component.tsに値を渡す。
AppComponentのselectedHeroをHeroDetailComponentのheroに受け渡す。

まずは、hero-detail.component.tsに@angular/coreに定義されているInputをimportする。
Inputをimportしたことで、@Inportデコレータが使えるようになる。

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

HeroDetailComponentのheroは外部から渡される変数なので、@Inputデコレータをつける。

@Input() hero: Hero;

AppModuleにHeroDetailComponentを宣言する

すべてのコンポーネントは、NgModuleに宣言されるべき。
ということで、app.module.tsを開き、HeroDetailComponentをimportする。

import { HeroDetailComponent } from './hero-detail.component';

加えて、modulesの中のdeclarationsにも追加する。

declarations: [
  AppComponent,
  HeroDetailComponent
],

declarations配列は、モジュールに属するコンポーネントやパイプ(こいつは一体??)やディレクティブを含める。
他のコンポーネントがモジュールを参照できるようになる前に、コンポーネントはmoduleに宣言されるべき。

hero-detailセレクタを呼び出す

HeroDetailComponentをAppModuleに宣言したことで、app.component.tsでも使用できるようになった。
なので、templateでhero-detailセレクタを使用する。

<hero-detail [hero]="selectedHero"></hero-detail>

hero変数を[]で囲み、=の右辺に渡したい値を記述することで、HeroDetailComponentのheroに値を渡すことができる。

終わりに

動作は前回と同じだが、サブコンポーネントとクラスに切り出したことでだいぶAppComponentがすっきりした。
まだまだリファクタリングの余地があるということで、次回でもリファクタリングを行うらしい。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1