Angularチュートリアルをやってみて -2-
チュートリアルを一通りやってみたが、よく分からなかった。
理解を深めるために、やった内容を書き出してみる。
今回はデータバインディングの基本を復習する。
データバインディング
データバインディングは、コンポーネントとテンプレート(ビュー)を紐付ける仕組み。Angularのデータバインディング構文は、データの流れる方向によって、大きく4種類に分類できる。
No. | データ方向 | 種類 | 記法 |
---|---|---|---|
1 | コンポーネント=>ビュー | Interpolation(補間 | {{...}} |
2 | コンポーネント=>ビュー | プロパティ/属性バインディング | [property]="Value" |
3 | ビュー=>コンポーネント | イベントバインディング | (event)="handler" |
4 | コンポーネント<=>ビュー | 双方向バインディング | [(target)]="Value" |
チュートリアル内のヒーローエディタの章で使ったのは、1と4である。違いとしては、双方向でデータのやり取りができるかどうかである。双方向バインディングでは、コンポーネントのプロパティとテキストボックスを同期させることで、テキストボックスの更新により、プロパティ値に反映させることができる。
Interpolation(補間)構文
最も初歩的なバインド記法であるInterpolation(補間)は、 {{...}}
で表現される。
サンプルコード
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<h1>Hello {{name}}</h1>`,//--------------------2 }) export class AppComponent { name = 'Angular'//----------------------------------------1 }
1 で定義されたnameプロパティを 2 で{{name}}
として参照している。
{{...}}式の注意点
1.利用できない演算子がある
主に副作用を伴う演算子は、{{...}}
式では禁止されている。
2.グローバル名前空間のオブジェクトを参照できない
{{...}}
式のコンテキストは、コンポーネントのインスタンスである。window、Mathのようなグローバル名前空間上のオブジェクトに{{...}}
式からアクセスすることはできない。
3.{{...}}式を利用する上でのガイドライン
- 式が副作用を伴わないこと(=他の値に影響がでないこと)
- 短時間で実行できること
- シンプルであること
- 同じ操作を何度実行しても同じ結果を返すこと
Angularでは、{{...}}
式を何度も評価する。時間のかかる式は、そのままアプリの速度低下につながる可能性があるので、注意が必要。
「?.」演算子
{{...}}
式だけで利用できる演算子に「?.」演算子がある。これはオブジェクトが空であるか判断し、空でない場合にだけプロパティにアクセスする。
双方向バインディング
コンポーネントクラスから画面へ、そして画面からコンポーネントクラスへのデータフローを作る。
<input>
フォーム要素とプロパティとの間に双方向データバインディングの設定をする。サンプルコードは以下のようになる。
<!--app.component.html--> <input type="text" [(ngModel)]="text" /> <label>{{text}}</label>
//app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { public text: string = "hoge"; }
[(ngModel)]
は双方向データバインディング構文。
ngModel
はデフォルトでは使用できない。理由は、オプションのFormsModule
に属しており、使用するにはモジュールをオプトインする必要がある。
//app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { FormsModule } from '@angular/forms';// <---追加 @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FormsModule// <---追加 ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
まとめ
[(ngModel)]
を使い、双方向データバインディングをすると、データのやり取りできる。単純に参照するだけなら、{{...}}
の形で書けばよいのではないか。