トピック
Angular2 CORE DOCUMENTATIONのGUIDEの翻訳です。
- DOCUMENTATION OVERVIEW - ドキュメント概要 -
- ARCHITECTURE OVERVIEW - 構文概要 -
- DISPLAYING DATA - データ表示 -
- USER INPUT - ユーザー入力 -
- FORMS - フォーム -
- DEPENDENCY INJECTION - 依存性注入 -
- STYLE GUIDE - スタイルガイド -
注意1)ここに掲載されていない項目は、Angular2 CORE DOCUMENTATIONのGUIDEを直接参照してください。
注意2)2016年10月7日時点の翻訳です。翻訳者はTOEICで700点くらいの英語力なので、英訳が間違っている可能性があります。しかもかなり意訳している箇所もあります。もし意訳を通り越して、誤訳になっているような箇所がありましたらご指摘ください。
DISPLAYING DATA - データ表示 -
アプリケーションデータをUIに反映させるときは、プロパティバインディングが役立ちます。
HTMLテンプレートにある管理対象を、Angularコンポーネントのプロパティに紐づけることでデータが表示されます。
このページでは、heroesリストを使ったコンポーネントを作っていきます。
heroの名前リストを表示させ、暫定的にその下にメッセージを出力するようにします。
最終的なUIはこのようになります。
Contents - コンテンツ -
live exampleで、このページにあるシンタックスとコードスニペットを全て試すことができます。
内挿を使って、コンポーネントのプロパティを表示
コンポーネントのプロパティを表示させる手っ取り早い方法は、内挿を使ってプロパティ名とバインディングしてしまうことです。
内挿は、ビューテンプレートにあるプロパティ名を{{myHero}}
のように二重波括弧でくくることで使用できます。
図のようなサンプルを作るために、displaying-data
という新しいプロジェクトフォルダを作り、QuickStartの手順に従って始めてみてください。
もしくはQuickStartのソースをダウンロードして始めてください。
コンポーネントのテンプレートとbodyを変更して、app.component.ts
ファイルを修正します。
その作業が終わると、このようになります。
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>
`
})
export class AppComponent {
title = 'Tour of Heroes';
myHero = 'Windstorm';
}
2つのプロパティを、元々空のコンポーネント(title
とmyHero
)に加えました。
二重波括弧の内挿を使うと、2つのコンポーネントプロパティが修正したテンプレートに表示されます。
template: `
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>
`
このテンプレートは、ECMAScript 2015のバッククウォート( ` )を使った複数行の文字列です。バッククウォート( ` )(シングルクウォート(
'
)とは違う文字)を使うと、文字列を複数行にわけ、HTMLを読みやすくすることができます。
Angularは自動的にコンポーネントからtitle
とmyHero
の値を引き出して、ブラウザにある対応した値へ挿入します。これらのプロパティが変更されると、Angularは画面の更新を行います。
より正確にいうと、キーボードの操作やタイマーの完了、HTTPリクエストに対するレスポンスなど、ビューに関連する非同期のイベントが起こった後に再描画が始まります。
新しくインスタンスを作るために、AppComponent
クラスを呼び出す必要がないことに注意してください。Angularはすでにインスタンスを作っています。さて、どうやって作っているのでしょうか?
@Component
デコレータにあるCSSselector
は、my-app
と名付けられた要素を判別します。
QuickStartを振り返ってみてください。<my-app>
要素が、index.html
ファイルのbodyに追加されているはずです。
<body>
<my-app>loading...</my-app>
</body>
(main.ts
の中で)AppComponent
クラスを起動させると、Angularはindex.html
にある<my-app>
を探し出し、AppComponent
のインスタンスを作って<my-app>
タグの中にレンダリングします。
そしてアプリが動き出し、titleやhero nameも表示されます。
次以降のセクションで、アプリ内で使用されるコーディング方法をいくつか紹介しています。
インラインテンプレートか、テンプレートファイルか
コンポーネントのtemplate
は、2つある場所のうち、どちらかの中に入れておくことができます。template
プロパティを使ってインラインで定義するか、@Component
デコレータにあるtemplateUrl
プロパティを使って、分離したHTMLファイルと紐づけて定義するかのどちらかです。
インラインにするか、分離したHTMLにするかという選択は、各人の好みや状況、組織のポリシーによって行ってください。このアプリでは、テンプレートが小さく、追加HTMLファイルもない簡単なデモを使っているので、インラインのHTMLを使用します。
どちらのスタイルであっても、テンプレートデータバインディングはコンポーネントのプロパティと同じように繋がります。
コンストラクタか、変数の初期化か
この例ではコンポーネントの初期化に代入変数を使用していますが、その代りにコンストラクタを使って、プロパティの初期化と宣言を行うこともできます。
export class AppCtorComponent {
title: string;
myHero: string;
constructor() {
this.title = 'Tour of Heroes';
this.myHero = 'Windstorm';
}
}
このアプリでは、簡潔性を保つため、より簡単な「代入変数」の方式を使っていきます。
ngForを使って、配列のプロパティーを表示
heroesリストを表示させるため、まずはコンポーネントにhero namesの配列を追加し、配列の最初の名前になるようmyHero
を再定義します。
export class AppComponent {
title = 'Tour of Heroes';
heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado'];
myHero = this.heroes[0];
}
次にテンプレートにあるAngularのngFor
ディレクティブを使って、heroes
リストにあるそれぞれの項目を表示させます。
template: `
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>
<p>Heroes:</p>
<ul>
<li *ngFor="let hero of heroes">
{{ hero }}
</li>
</ul>
`
このUIでは、<ul>
と<li>
のタグを使用して、HTMLの番号なしリストを使用しています。<li>
要素にある*ngFor
は、Angularにある「リピーター」ディレクティブです。それを使うと、<li>
要素(と、その子要素)は「リピーターテンプレート」としてマークアップされます。
<li *ngFor="let hero of heroes">
{{ hero }}
</li>
*ngFor
ではアスタリスク(*)を忘れないようにしてください。このシンタックスでの重要事項となります。もっと詳しく知りたい場合は、Template Syntaxページを参照してください。
ngFor
の2重引用符内で指示されているhero
に注目してください。変数をテンプレート内で入力している一例です。テンプレート内で変数を入力することについてもっと知りたい場合は、 Template Syntaxページの microsyntaxセクションを読んでください。
*ngFor
のイテレーション(繰り返し)の中で、Angularはリストにあるアイテムごとに<li>
を複製し、各アイテム(hero)に対してhero
変数を設定します。そのとき、Angularでは2重波カッコの内挿がある文脈が変数として扱われます。
この場合、
ngFor
は配列を表示していますが、 イテラブル(繰り返し可能な)オブジェクトのアイテムをリピートさせることもできます。
これで番号なしリストにheroesが表示されます。
データ用のクラスを作る
コンポーネントの中に直接データを定義することはあまり推奨される方法ではありませんが、簡単なデモであれば、そのような実装でも構いません。
その場合、文字列の配列とバインディングすることになりますが、実際のアプリケーションではほとんどの場合、より特殊なオブジェクトとバインディングすることになります。
こういった特殊なオブジェクトのバインディングを変換するときは、hero namesの配列をHero
オブジェクトの配列に変えておくといいです。そのために、Hero
クラスを用意しておく必要があります。
app
フォルダの中に、hero.ts
と呼ばれる新しいファイルを次のコードを付けて作成してください。
export class Hero {
constructor(
public id: number,
public name: string) { }
1つのコンストラクタと2つのプロパティ(id
とname
)を持ったクラスを定義しました。
プロパティを持ったクラスのようにはみえないかもしれませんが、ちゃんと持っています。コンストラクタにおけるパラメータの宣言は、TypeScriptショートカットの利点を利用しています。
最初のパラメータを検証してみましょう。
public id: number,
簡単なシンタックスですが、色々とやっています。
- コンストラクタのパラメータとその型を宣言している。
- 同じ名前のpublicなプロパティを宣言している。
- クラスのインスタンスを作るときに、対応する引数を持つプロパティを初期化している。
Heroクラスを使う
コンポーネント内にあるheroes
プロパティは、Hero
オブジェクトを返すHero
クラスを使えるようになっています。
heroes = [
new Hero(1, 'Windstorm'),
new Hero(13, 'Bombasto'),
new Hero(15, 'Magneta'),
new Hero(20, 'Tornado')
];
myHero = this.heroes[0];
次に、テンプレートを更新します。今まではheroの id
とname
を表示していましたが、heroのnameプロパティのみを表示するように修正します。
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>
`
表示は同じように見えますが、コードはかなりすっきりしました。
ngIfを使って、条件による表示
ある一定の状況下でのみ、ビューもしくはビューの一部を表示したいということがあります。
heroが4人以上いる場合にメッセージが表示されるよう、サンプルを変更してみましょう。
AngularのngIfディレクティブは、truthy/falseyという条件に基づいて要素を挿入もしくは除去を行います。アクションでそれを確認する場合は、テンプレートの最後に次の段落を加えてください。
<p *ngIf="heroes.length > 3">There are many heroes!</p>
*ngIf
の最初にアスタリスク(*)を忘れずにつけてください。このシンタックスでの重要事項となります。ngIf
と*についてもっと詳しく知りたい場合は、 Template Syntax ページのngIf sectionを読んでください。
*ngIf="heros.length > 3"
という2重引用符に囲まれたテンプレートの表現は、TypeScriptのような見た目と反応を示します。heroesのコンポーネントリストが4つ以上のアイテムを持っていると、AngularがDOMに段落を加え、メッセージが表示されます。
もしアイテムが3つ、もしくはそれ以下だった場合、Angularは段落を削除し、メッセージが非表示になります。
より詳しい情報は、 Template Syntax ページのtemplate expressionsセクションを確認してください。
Angularは、メッセージを表示、非表示にするわけではありません。DOMに対し、段落要素を追加、削除しているのです。これによってパフォーマンスの改善が見込まれ、特にデータバインディングによって、大量のHTMLを条件次第で出し入れするような巨大プロジェクトの場合には、大きな効果が発揮されます。
さあ、やってみてください。4つのアイテムをもつ配列なら、メッセージが現れるはずです。app.component.ts
に戻って、heroの配列から要素を1つ削除するか、コメントアウトしてみてください。ブラウザが自動的にリフレッシュされ、メッセージが消えるはずです。
Summary - 総括 -
以下の使い方について学習しました。
- 2重波カッコでくくられたInterpolationは、コンポーネントのプロパティを表示します。
- ngFor は複数のアイテムを持った配列を表示します。
- TypeScriptのクラスはコンポーネント用にモデルデータを形成し、そのモデルのプロパティを表示します。
- ngIfは条件の真偽に基づいて、HTMLのブロックを表示させます。
最終的なコードです。
import { Component } from '@angular/core';
import { Hero } from './hero';
@Component({
selector: 'my-app',
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>
`
})
export class AppComponent {
title = 'Tour of Heroes';
heroes = [
new Hero(1, 'Windstorm'),
new Hero(13, 'Bombasto'),
new Hero(15, 'Magneta'),
new Hero(20, 'Tornado')
];
myHero = this.heroes[0];
}
export class Hero {
constructor(
public id: number,
public name: string) { }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
imports: [
BrowserModule
],
declarations: [
AppComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
Next Step
USER INPUT - ユーザー入力 -