はじめに
Angular 2はGoogleとオープンソースコミュニティで開発されているJavaScriptフレームワークで、現行AngularJS(AngularJS 1)の次期バージョンです。2016年8月時点のバージョンは2.0.0-rc.5で、まもなく正式リリースという状況になっています。Angular 2はAngularJS 1に対して多くの変更点があり、コードの記述法も基本的に異なります。
AngularJS 1ではビューとデータモデルを関連付けるデータバインディングや、ディレクティブと呼ばれる独自のHTML記述が利用できました。これらはAngularJSの特徴として真っ先に言及される機能で、Angular 2でももちろん利用できます。しかし記述方法が微妙に異なっており、最初は違和感を感じるかもしれません。
そこで本記事では、Angular 2でデータバインディングやディレクティブを利用する方法を、AngularJS 1と比較しながら説明していきます。
対象読者
- AngularJS 1は経験があるが、Angular 2は分からない方
- Angular 2正式版リリースを待ち望んでいる方
- 最新フレームワークに触れておきたい方
必要な環境
Angular 2はJavaScriptのフレームワークですが、公式WebサイトのドキュメントやサンプルはTypeScriptが先行して整備される場合が多く、本連載でもTypeScriptでコードを記述していきます。また、サンプルの実行にはNode.jsが必要になります。
今回は以下の環境で動作を確認しています。
-
Windows 10 64bit版
- Node.js v6.4.0 64bit版
- Microsoft Edge 38.14393.0.0
Angular 2の公式Webサイトでは基本的なAngular 2の実行環境を整える手順「5 MIN QUICKSTART」を公開しており、本記事も基本的にこのクイックスタートで作成したファイル一式をベースにサンプルコードを記述します。クイックスタートの実行方法については前回記事も参照してください。なお、2016年8月現在の手順で作成したクイックスタートプロジェクト(angular2-quickstart)を、ダウンロードできるサンプルコードに含めています。
参考 2.0.0-rc.5でのクイックスタートの変更点
2.0.0-rc.5のリリースとともに、クイックスタートの内容も変更されています。参照するモジュールのバージョンが変更されたほか、Webアプリのモジュールを定義するapp/app.module.tsファイルが追加され、そのモジュールをapp/main.tsのアプリ起動処理が参照するようになっています。クイックスタートプロジェクトのapp.module.tsはリスト1のようになっており、Webブラウザーでアプリを実行するためのBrowserModuleモジュールと、app.component.tsに実装されたコンポーネントAppComponentを参照して、WebアプリのモジュールAppModuleを定義しています。
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 { }
app.module.tsのモジュール記述については次回の連載で詳しく説明します。なお本記事のサンプルコードではリスト1をもとに、フォームを利用するサンプルではフォームのモジュール(FormsModule)を追加しています。
記述法がちょっと違うデータバインディング
データバインディングは、コンポーネントが公開している変数やメソッドをWebコンテンツ(HTML)から参照・更新する仕組みです。Angular 2でデータバインディングを利用するシンプルな例をリスト2に示します。Angular 2のコンポーネント定義については前回記事の説明も参考にしてください。
import { Component } from "@angular/core"; // コンポーネントのメタデータを設定(Decorator) ...(1) @Component({ selector: "my-app", template: ` <h1>Angular 2 サンプル1</h1> <h3>片方向データバインディング</h3> <!-- {{ }}記述で片方向データバインディング ...(2)--> <p>{{message}}</p> <h3>双方向データバインディング</h3> <!-- [(ngModel)]属性で双方向データバインディング ...(3)--> <input type="text" [(ngModel)]="message"> ` }) export class AppComponent { // バインディング変数 ...(4) message:string = "こんにちは!"; }
(1)内のtemplateパラメータが、コンポーネントの表示を定義するHTMLです。バッククォート(`)で囲むと複数行を記述できます。コンポーネントが公開している変数の内容を参照するだけ(片方向データバインディング)の場合は、(2)のように「{{ }}」で変数名を囲んで記述します。一方、HTMLで変数の参照と変更を両方行う(双方向データバインディング)場合は、(3)のようにタグの「[(ngModel)]」属性に変数名を記述します。データバインディングの対象となる変数messageは(4)で定義されています。
リスト2を実行すると、変数messageの内容がラベル(pタグ要素)とテキストボックスに表示されます。テキストボックスの内容を書き換えると、ラベルの表示も連動して変更されます。
AngularJS 1では、片方向データバインディングは同一の記述ですが、双方向データバインディングはリスト3のように、[(ngModel)]の代わりにng-model属性を利用します。リスト3を含むコード全体はダウンロードできるサンプルコードに含まれています。
<!-- ng-model属性で双方向データバインディング --> <input type="text" ng-model="message">
参考 テンプレートのHTMLを外出しする
リスト2ではコンポーネントファイル内のtemplate属性に直接テンプレートのHTMLを指定しましたが、HTMLを別ファイルに外出しして、templateUrl属性にHTMLファイルのパスを指定することもできます。特にコードが大規模になった場合に、表示とロジックを分離して整理できます。
@Component({ selector: "my-app", templateUrl:"app/template.html" // app/template.htmlにHTMLが記述されている })
リスト4を含むコード全体(angular2-001a-templateUrl)はダウンロードできるサンプルコードに含まれています。本記事ではサンプルコードの処理全体を見通せるようにするため、リスト2のようにtemplate属性にHTML記述を直接指定しています。