前のページ

次のページ


データを表示する

このページではクイック・スタートで使ったアプリを加工しながらデータの表示法を学習します。最終的には次のような表示となります:


このアプリの最終的なコードはGitHubからダウンロードできます。またライブで試すこともできます。更に筆者による「プログラミング言語Dartの基礎」の添付資料のdart_code_samplesappsにも同じものがangular2_displaying-dataとして含めてありますので、すでにdart_code_samplesが自分のIDE上にある場合はそちらも使えます。



********



このページでは以下の項目を学習します:



内挿でコンポネントのプロパティを表示する

コンポネントのプロパティを表示させる最も簡単な手段は内挿を介してそのプロパティの名前をバインドすることです。内挿を使う場合はビュー・テンプレートの二重波括弧で囲んだ中にそのプロパティの名前を{{myHero}}のように置きます。

早速それを試してみましょう。

最初にクイック・スタートで使ったアプリをIntelliJ上に展開します。

  1. IDE上でFile → Openquickstartのフォルダを選択する

  • もし”Enable Dart support”というメッセージが表示されていたら、そのリンクをクリックする

  • もし"'Pub get'has not been run”というメッセージが表示されていたら、Get dependenciesのリンクをクリックする。このコマンドの実行にはしばらく時間がかかります

  • それでもIDE上でエラーが表示されている場合は、Repair cashe..を実行してみてください(これも時間がかかります)

  1. app_component.dartファイルをコード・ビュー上に表示させ、このコードを以下のコードに置き換える(コピー/ペースト)

lib/app_component.dart

import 'package:angular2/core.dart';
@Component(
    selector: 'my-app',
    template: '''
      <h1>{{title}}</h1>
      <h2>My favorite hero is: {{myHero}}</h2>
    '''
)
class AppComponent {
  String title = 'Tour of Heroes';
  String myHero = 'Windstorm';
}

ここではこのコンポネントにtitlemyHeroという2つの属性を持たせています。

書き換えたテンプレートは二重波括弧を使ってこの2つのコンポネント・プロパティを表示させています。

template: '''
  <h1>{{title}}</h1>
  <h2>My favorite hero is: {{myHero}}</h2>
'''

Angularはこのコンポネントから自動的にtitlemyHeroプロパティの値をとりだし、これらの値をブラウザに挿入します。Angularはこれらのプロパティ値の変更があったときはこの表示を更新します。

より精密に言えば、この再表示はキー・ストローク、タイマの完了、あるいは非同期XHR ( XMLHttpRequest) 応答といったようなビューに関連した何らかの非同期イベントの後に発生します。これらのサンプルはここにはありません。従ってどっちにしてもこれらのプロパティは自分で変化することはありません。

AppComponentクラスのインスタンスを生成するのにnewを呼んでいないことに注意してください。Angularが我々のためにインスタンスを生成しているのです。どうやってでしょうか?

@ComponentアノテーションのなかのCSSセレクタがmy-appという名前の要素を指定していることに注意してください。クイック・スタートではindex.htmlファイルのbody部に<my-app>要素が付加されていることを思い出してください:

web/index.html (body)

<body>
  <my-app>Loading AppComponent content here ...</my-app>
</body>

この AppComponentクラスを起動させたとき、Angularindex.htmlのなかの<my-app>を探し、見つかったらAppComponentのインスタンスをインスタンス化し、それを<my-app>タグの内側に描画します。

このアプリを試してみましょう。IDE上でこのindex.htmlを右クリックし、Open in browserからDartiumを選択してください。次のようにタイトルとヒーロ名が表示されます。




テンプレートはインラインか別ファイルか?

自分たちのテンプレートの置き場所はふたつあります。今見たように@Comonentアノテーションの中のtemplateプロパティを使ってインラインで定義できます。あるいは、このテンプレートを別のHTMLファイルのなかで定義し、それを@ComponentアノテーションのtemplateUrlプロパティを使ってこのコンポネント・メタデータのなかでリンクさせることもできます。

インラインか分離したHTMLかは趣味、状況、あるいは皆さんの部門のポリシーの問題です。ここではテンプレートが小さく、またこのデモはさらなるHTMLファイルなしのほうがシンプルなためインラインのHTMLを使っています。

どちらのスタイルにおいても、テンプレートのデータ・バインディングはこのコンポネントのプロパティたちへのアクセスは同じです。



*ngForを使ってリストプロパティを表示する

ヒーロたちのリストのheroesを表示させたいとしましょう。まずこのコンポネントにヒーロの名前のリストを付加し、このリストの最初の名前となるようmyHeroを再定義することから始めましょう。

lib/app_component.dart (class)

class AppComponent {
  String title = 'Tour of Heroes';
  List<String> heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado'];
  String get myHero => heroes.first;
}

ここでヒーロたちのリストの中の各アイテムを表示させるためにテンプレートの中で AngularngForディレクティブを使います。

lib/app_component.dart (template)

template: '''
  <h1>{{title}}</h1>
  <h2>My favorite hero is: {{myHero}}</h2>
  <p>Heroes:</p>
  <ul>
    <li *ngFor="let hero of heroes">
      {{ hero }}
    </li>
  </ul>
'''

ここでは馴染みのHTML順序なしリストの<ul><li>タグが使われています。このなかのリスト・アイテムの<li>に注意してください。

<li *ngFor="let hero of heroes">
  {{ hero }}
</li>

<li>要素の中にいささかミステリアスな*ngForが付加されました。これがAngularの繰り返し("repeater")ディレクティブです。<li>タグの中にこれがあるとこの<li>要素(及びその子供たち)を繰り返しテンプレート("repeater template")にしてしまいます。

*ngForのなかのアスタリスク(*)を忘れないでください。この構文ではこれは不可欠な部分になります。これと ngForに関する詳細はテンプレートの構文の章を読んでください。

ngFor二重引用符命令のなかのheroに注目してください;これがテンプレート入力変数(template input variable)の一例です。

Angularはこのリストの中の各アイテムに対し<li>を繰り返し、現在の繰り返しのなかでのアイテム(hero)をこのhero変数にセットします。Angularはこの変数を二重波括弧のなかの内挿のためのコンテキストとして使います。

ここではたまたまあるリストの表示のために ngForを使っています。実はngForIterableを実装したクラスのオブジェクトでさえあればそのアイテムに対し繰り返すことが可能です。

これをDartiumで走らせてみると、ヒーロたちが順序なしリストの中で表示されます。




データのためのクラスを作る

現時点では我々のコンポネントの中で直接データを定義しています。デモにはこれでも良いのですが、確かにベスト・プラクティスとは言えません。グッド・プラクティスでさえもありません。この章ではこの件に対して何も対処していませんが、今後この問題を解決するために銘記しておくこととします。

現在我々は文字列のリストをバインドしています。我々は実際のアプリケーションではそうするのはたまたまであって、ほとんどの場合はもっと特化したオブジェクトをバインドしています。

ヒーロ名のリストをHeroオブジェクトたちのリストに変えてみましょう。そうするにはHeroクラスが必要になります。libフォルダの中に以下のコードをもった hero.dartという名前の新規のファイル作ります。

  1. IDE上のパッケージ・ビュー上のlibフォルダを右クリック→New→Filehero.dartファイル作成を指示

  2. コード・ビュー上のこのファイルに以下のコードをペーストする:

lib/hero.dart (抜粋)

class Hero {
  final int id;
  String name;
  Hero(this.id, this.name);
  String toString() => '$id: $name';
}

これでコンストラクタ、二つのプロパティ(idname)、及びtoString()メソッドを持ったクラスを定義しました。



Heroクラスを使う

それでは我々のコンポネントのなかのherosプロパティがこれらHeroオブジェクトたちのリストを返すようにしましょう。

lib/app_component.dart (heroes)

class AppComponent {
  String title = 'Tour of Heroes';List<Hero> heroes = [
    new Hero(1, 'Windstorm'),
    new Hero(13, 'Bombasto'),
    new Hero(15, 'Magneta'),
    new Hero(20, 'Tornado')
  ];
  Hero get myHero => heroes.first;
}

このままだとIDEHeroクラスがないと苦情を言うので、以下の文を最初に付さねばなりません:

lib/app_component.dart (inport)

import 'hero.dart';

我々のコンポネントのなかのherosプロパティがこれらのHeroオブジェクトたちのリストを返すようにしましょう。

lib/app_component.dart (heroes)

class Hero {
  final int id;
  String name;
  Hero(this.id, this.name);
  String toString() => '$id: $name';
}

いずれテンプレートもアップデートが必要になるでしょう。現在このテンプレートではtoString()がオーバライドされていてheroidnameを表示します。heronameプロパティのみを表示するようこれを直しましょう。

lib/app_component.dart (template)

template: '''
  <h1>{{title}}</h1>
  <h2>My favorite hero is: {{myHero.name}}</h2>
  <p>Heroes:</p>
  <ul>
    <li *ngFor="let hero of heroes">
      {{ hero.name }}
    </li>
  </ul>
  <p *ngIf="heroes.length > 3">There are many heroes!</p>
''')

この状態でこのアプリをDartiumで開くと結果は全く変わりませんが、我々はheroは実際何なのかがずっと良く理解できます。



*NgIfによる条件表示

しばしばあるアプリにおいて特定の状況においてのみビューまたはビューの一部を表示することがあります。

我々のサンプルで、もしヒーロたちの数が多くなった(例えば3以上)場合表示したいと思います。

AngularngIf

ディレクティブはブール状況に応じある要素を挿入または削除します。我々はこのテンプレートの最後の箇所で以下のパラグラフを追加することでこれを実際に確認できます:

lib/app_component.dart (message)

<p *ngIf="heroes.length > 3">There are many heroes!</p>


*ngIfのなかのアスタリスク(*)を忘れないでください。この構文ではこれは不可欠な部分になります。これと ngIfに関する詳細はテンプレートの構文の章を読んでください。

2重引用符で囲まれた内側はDartの文とよく似ています。このコンポネントのheroたちのリストが3アイテム以上になると、Angularはこのパラグラフを追加しそのメッセージが表示されます。アイテム数が3またはそれ以下の場合はAngularはそのパラグラフをオミットし、メッセージは表示されません。

Angularはメッセージを見せたり隠したりしてはいません。Angularはこのパラグラフ要素をDOMに追加したり削除したりします。ここではそれは全く問題ではではありません。しかし多くのデータ・バインディングを持った大きなHTMLを条件に応じて追加・削除することになった場合は、これは性能の観点からすればかなり問題になります。

これを試してみてください。このリストは既に4アイテムを持っているので、このメッセージが表示されます:


app_component.dartに戻って、4つの要素のうち一つを削除またはコメント・アウトしてみてください。ブラウザを再読み込みさせると、このメッセージが消えることを確認してください。



まとめ

これで以下のものの使い方が理解できたはずです:

  • コンポネントのプロパティを表示する為の2重波括弧を使った文字列内挿

  • アイテムたちのリストを表示するためのngFor

  • 我々のコンポネントのためのモデル・データを形成し、そのモデルのプロパティたちを表示するためのDartのクラス

  • ブール式に基づきHTMLの一部を条件付きで表示するためのngIf

最終的なコードはGitHubから取得できます。また筆者による「プログラミング言語Dartの基礎」の添付資料のdart_code_samplesappsにも同じものがangular2_displaying-dataとして含めてありますので、すでにdart_code_samplesが自分のIDE上にある場合はそちらも使えます。


前のページ

次のページ