LoginSignup
6
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-12-14

はじめに

前回クイックスタートを行ってある程度Angularがわかってきた。

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

「英雄ツアー?(Tour of Heroes)」

Angularのチュートリアルはなかなかシャレが効いてる。
ということで、チュートリアルを進めてみます。

ディレクトリ名を変える

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

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

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

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

タイトルを変更

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

$ npm run tsc
$ npm start

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

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

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

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

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

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の上部に追加

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);

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

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

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);

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

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を書いている人にはおなじみのアレですね。

ヒーロー名を編集

次はデータを受け取る処理を書きます。

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部分を以下のようにします。

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

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

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

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

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ファイルとして書き出せないととても不便だ。
この辺りをどのように解決するのかを期待して次のチュートリアルに進んでみる。

6
6
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
6
6