Angular 2 のチュートリアル「Tour of Heroes」をやってみる。

## はじめに
[前回](http://qiita.com/syou007/items/99e854de7a30a97042b9)クイックスタートを行ってある程度Angularがわかってきた。

で、チュートリアルをやろうと思ったのだが・・・

「英雄ツアー？（Tour of Heroes）」

Angularのチュートリアルはなかなかシャレが効いてる。
ということで、[チュートリアル](https://angular.io/docs/ts/latest/tutorial/)を進めてみます。

## ディレクトリ名を変える
まずは`angular2-tour-of-heroes`にディレクトリ名を変えろとあるので変更する。

```sh
$ cd ../
$ mv angular2-quickstart/ angular2-tour-of-heroes/
$ cd angular2-tour-of-heroes
```

あと、前回の謎で`TypeScript`の感知に関しては常に`npm run tsc`を起動しておくという事だった。
なるほどー。

ところで、この辺りは`grant`などは使う必要なしなのかな・・・？
`tsc`だけで十分の気がするからこれだけでいいのかな？

## タイトルを変更
事前に以下のコマンドを二つのターミナルで実行しておく。

```sh
$ npm run tsc
```

```sh
$ npm start
```

チュートリアルに以下を追加とあるので、`app.ts`に追加してみる。

```ts:src/app/app.ts
class AppComponent {
  public title = 'Tour of Heroes';
  public hero = 'Windstorm';
}
```

あと以下も追加と書かれているので追加。

```ts
template: '<h1>{{title}}</h1><h2>{{hero}} details!</h2>'
```

結果以下のようになった。

```ts:src/app/app.ts
import {bootstrap, Component} from 'angular2/angular2';
@Component({
    selector: 'my-app',
    template: '<h1>{{title}}</h1><h2>{{hero}} details!</h2>'
})
class AppComponent {
  public title = 'Tour of Heroes';
  public hero = 'Windstorm';
}

bootstrap(AppComponent);
```

ブラウザは以下のようになった。

```
Tour of Heroes

Windstorm details!
```

自動的に変更されるのは本当にすごい！
ただ、仕組み（因果関係）が未だにわからない。

## ヒーローを表示
ヒーロー用のクラスを上部に追加しろと書かれているので以下を`app.ts`の上部に追加

```ts:src/app/app.ts
import {bootstrap, Component} from 'angular2/angular2';
class Hero {
  id: number;
  name: string;
}
@Component({
    selector: 'my-app',
    template: '<h1>{{title}}</h1><h2>{{hero.name}} details!</h2>'
})
class AppComponent {
  public title = 'Tour of Heroes';
  public hero: Hero = {
    id: 1,
    name: 'Windstorm'
  };
}

bootstrap(AppComponent);
```

結果的に上記のような状態を作成する。

これを実施後にもっと詳細を出すためにというトピックがあるので、さらに以下のように変更

```ts:src/app/app.ts
import {bootstrap, Component} from 'angular2/angular2';
class Hero {
  id: number;
  name: string;
}
@Component({
    selector: 'my-app',
    template: '<h1>{{title}}</h1><h2>{{hero.name}} details!</h2><div><label>id: </label>{{hero.id}}</div><div><label>name: </label>{{hero.name}}</div>'
})
class AppComponent {
  public title = 'Tour of Heroes';
  public hero: Hero = {
    id: 1,
    name: 'Windstorm'
  };
}

bootstrap(AppComponent);
```

このままだとテンプレートが読みにくいのでヒアドキュメントを使うと以下のようになる。

```ts:src/app/app.ts
import {bootstrap, Component} from 'angular2/angular2';
class Hero {
  id: number;
  name: string;
}
@Component({
    selector: 'my-app',
    template: `
<h1>{{title}}</h1>
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div><label>name: </label>{{hero.name}}</div>`
})
class AppComponent {
  public title = 'Tour of Heroes';
  public hero: Hero = {
    id: 1,
    name: 'Windstorm'
  };
}

bootstrap(AppComponent);
```

シングルクォート(')ではなくバックティック(`)である事に注意！
Qiitaを書いている人にはおなじみのアレですね。

## ヒーロー名を編集
次はデータを受け取る処理を書きます。

```ts:src/app/app.ts
import {bootstrap, Component} from 'angular2/angular2';
class Hero {
  id: number;
  name: string;
}
@Component({
    selector: 'my-app',
    template: `
  <h1>{{title}}</h1>
  <h2>{{hero.name}} details!</h2>
  <div><label>id: </label>{{hero.id}}</div>
  <div>
    <label>name: </label>
    <div><input value="{{hero.name}}" placeholder="name"></div>
  </div>
`
})
class AppComponent {
  public title = 'Tour of Heroes';
  public hero: Hero = {
    id: 1,
    name: 'Windstorm'
  };
}

bootstrap(AppComponent);
```

inputボックスを使って入力できるようにします。
しかし、これでは入力データは反映されないのでinput部分を以下のようにします。

```html
<input [(ng-model)]="hero.name" placeholder="name">
```

で`NgModel`を追加しろと言われますが・・・

```
EXCEPTION: No value accessor for ' ' in [null]
```

結局その後`FORM_DIRECTIVES`を使えと言われ、最終的に以下のようになります。

```ts:src/app/app.ts
import {bootstrap, Component, FORM_DIRECTIVES} from 'angular2/angular2';
class Hero {
  id: number;
  name: string;
}
@Component({
  selector: 'my-app',
  template:`
    <h1>{{title}}</h1>
    <h2>{{hero.name}} details!</h2>
    <div><label>id: </label>{{hero.id}}</div>
    <div>
      <label>name: </label>
      <div><input [(ng-model)]="hero.name" placeholder="name"></div>
    </div>
    `,
  directives: [FORM_DIRECTIVES]
})
class AppComponent {
  public title = 'Tour of Heroes';
  public hero: Hero = {
    id: 1,
    name: 'Windstorm'
  };
}
bootstrap(AppComponent);
```

これでブラウザで見たときにヒーロー名を変更すると即時反映されるようになります。

## 最後に
英語のせいか、プログラムのどの部分にコードを入れれば良いかがわかりにくい・・・
@Componentの「directives」の位置も「selector」より上に記載すると動かなかったりするし・・・。

とはいえ、Angularの特色であるデータバインドは健在で入力文字が即時反映されるのは素晴らしかった。
Angular1よりもHTMLへの負担が少なくなっているので、扱いやすくなっている感じがする。

しかも、@Componentのスコープ内にしか影響されなくなったためデータの変更点が一部だけになっているのも良い変更だと思う。
一方で、全体的に適用したい変数（{{hero.name}}をindex.htmlに書いても変換されない）の場合にどう書けば良いかがわからない。

また、template部分はhtmlファイルとして書き出せないととても不便だ。
この辺りをどのように解決するのかを期待して次のチュートリアルに進んでみる。