Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Angular2 The Tour of Heroes tutorial に挑戦してみる 3

MULTIPLE COMPONENTS

https://angular.io/docs/ts/latest/tutorial/toh-pt3.html

  • 複数のcomponentsを扱う場合の話か。

Make a hero detail component

  • Add a file named hero-detai.component.ts to the app/ folder. This file will hold the new HeroDetailComponent.
import { Component } from '@angular/core';

@Component({
  selector: 'hero-detail', //selectorは、css selectorで、このコンポーネントを呼び出すときに使う名前かな?
})
export class HeroDetailComponent{

}
  • export classは、どこからでも、importするために設定するのか。exportするとき(importするとき)の設定をここに書くのか。

Hero detail template

  • my-appのHero detailの部分を、カットしてペーストする。
@Component({
  selector: 'hero-detail',
  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>
  `
})

Add the hero property

  • hero: Hero; のclass定義をセットする。
export class HeroDetailComponent{
  hero: Hero;
}
  • このままでは、Heroが定義されていないので、Heroのclassの定義をする
  • 2つ以上のcomponentsで、Hero classが必要なので、別ファイルで、Hero classの定義をしてしまう。
  • src/app/hero.ts ファイルを作成する。
export class Hero{
  id: number;
  name: string;
}
  • AppComponent and HeroDetailComponent have to import it.
  • Add the following import statement near the top of both the app.component.ts and the hero-detail.component.ts files.
import { Hero } from './hero';
  • djangoとfrom と importが逆になっただけだな。

The hero property is an input property

  • どのheroを表示するかについては、親Componentである、AppComponentが子ComponentのHeroDetailComponent へと伝達する。selectedHeroをhero property of the HeroDetailComponent へとbindingすることで。

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

  • []でheroを囲んでいるのは, bindingのtargetにするため。
  • target binding property が、input propertyであることをdeclareする必要がある
  • otherwise, Angular rejects the binding and throws an error
  • First, amend the @angular/core import statement to include the Input symbol.

src/app/hero-detail.component.ts (excerpt)

import { Component, Input } from '@angular/core';
  • Then declare that hero is an input property by preceding it with the @Input decorator that you imported earlier.
export class HeroDetailComponent{
  @Input() hero: Hero;
}
  • bindingのためには、Inputの定義が必要とのこと。ここはまだよくわかってない。

Declare HeroDetailComponent in the AppModule

  • app.module.tsにimportする。app.module.tsがdjangoでいうところのsettings.pyに近いのかな。

Add the HeroDetailComponent to the 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>
  <hero-detail [hero]="selectedHero"></hero-detail>
`,

What changed?

  • You simplified the AppComponent by reducing its responsibilities.

  • You can evolve the HeroDetailComponent into a rich hero editor without touching the parent AppComponent.

  • You can evolve the AppComponent without touching the hero detail view.

  • You can re-use the HeroDetailComponent in the template of some future parent component.

  • オブジェクト指向に近いものと考えていいのかな?

 まとめ・気づき

  • componentは分割して再利用
  • componentをactiveにするには、app.module.tsに設定する(settings.pyみたいなもんか)
  • component.tsに記載する、export classは、他からimportするときに必要なclassの定義。
  • []は,bindingのtargetであることを示す(ことが多い?)。
  • inputされるpropertyの場合は、@Input デコレータを設定する。
  • classの定義が重複する場合は、それ用のtsファイルを用意してそっちに記載する。