Angular TIPS

Angular TIPS

Angular 2を利用するには?(実装編)

2016年12月6日

初めてのAngular 2開発。誤解のしようもない最も基本的な“Hello World”を作成して、Angular 2アプリの基本構造を理解しよう。

  • このエントリーをはてなブックマークに追加

 別稿「TIPS:Angular 2を利用するには?(準備編)」では、Angular 2とは、に始まり、Angular 2でアプリを開発するための基本的な設定とインストールを済ませました。本稿では、準備編で作成したアプリケーションフォルダーに対して、具体的なコードを追加していきます。作成するのは、初めてのサンプルの定番――「こんにちは、世界!」を表示するだけの、基本的なサンプルです(図1)。誤解のしようもない基本的なサンプルなので、「またか」と思わず、Angular 2アプリの基本的な構造を理解してください。

図1 決められたメッセージを表示するだけのサンプル
図1 決められたメッセージを表示するだけのサンプル

[1]モジュールを準備する

 モジュールとは、アプリを構成するオブジェクト(=コンポーネント)を束ねるための仕組みです。Angular 2それ自体も複数のモジュールから構成されており、アプリの要件に応じて必要なモジュールをインポートして利用することになります。

 もちろん、モジュールはアプリ開発者が自ら定義することもできます。原則として、Angular 2アプリは、1つ以上のモジュールから構成されていなければなりません。アプリを起動する際に呼び出されるモジュールのことを「ルートモジュール」とも呼びます(いわゆる、アプリのエントリーポイントを内包するメインモジュールです)。

 以下に、その具体的なコードを示します。なお、以降のコードは特筆しない限り、アプリケーションルート配下の/appフォルダーに保存するものとします。

TypeScript
// 1Angular 2で利用するモジュールをインポート
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

// 2AppComponentコンポーネントをインポート
import { AppComponent }  from './app.component';

// 4モジュールに関する情報を宣言
@NgModule({
  imports:      [ BrowserModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
// 3モジュールクラスを準備
export class AppModule { }
リスト1 ルートモジュールAppModuleを定義するためのコード(app/app.module.ts)

各番号の内容は本文で詳しく説明します。34は順番が逆になっているので注意すること。

 まず、import命令で、Angular 2アプリを動作させるのに必要となるモジュール/コンポーネントをインポートします。

[構文]import命令

import { name,…… } from module

  • name: インポートする要素
  • module: モジュール

 1@angular/~はAngular 2が提供する標準モジュールです。最低限、モジュールを定義するためのNgModule、ブラウザー上でアプリを動作させるためのBrowserModuleをインポートしておきましょう*1

  • *1 あくまで最小限の構成です。本格的なアプリでは、フォームを扱うためのFormsModule、ルーティング機能を提供するRouterModuleなどもインポートの必要があります。

 2AppComponentは、アプリの本体を表すコンポーネントです。後からあらためて定義します。

 そして、3AppModuleという名前のルートモジュール(=モジュールクラス)を準備しています。他のモジュールから呼び出す際などには、ここで宣言した名前(AppModule)を利用します。

 ただし、これだけではモジュールと見なされません。@NgModuleデコレーターでモジュールとしての情報を宣言しておきましょう(4)。デコレーターは、モジュールやクラスなどの要素に対してメタ情報を付与するための仕組みです。Javaでいうところのアノテーションに相当する仕組み、と考えると、分かりやすいかもしれません。デコレーターには「パラメーター名: 値」のハッシュ形式で、あらかじめ決められたパラメーター情報を指定できます。

 @NgModuleデコレーターで利用できるパラメーターには、以下のようなものがあります。

パラメーター名 概要
imports 現在のモジュールで利用する他のモジュール/コンポーネント
exports 現在のモジュールで外部に公開するコンポーネントなど
declarations モジュール配下のコンポーネント
bootstrap 最初に起動すべき最上位のコンポーネント(=ルートコンポーネント
表1 @NgModuleデコレーターの主なパラメーター

 この例であれば、「BrowserModuleを参照して」「ルートコンポーネントとしてAppComponentを含んだ」AppModuleモジュールを定義する、という意味になります。

[2]コンポーネントを準備する

 手順[1]で保留にしていたルートコンポーネントを作成します。ルートコンポーネント(もしくはメインコンポーネント)とは、アプリで最初に呼び出される、いわゆるエントリーポイントです。

TypeScript
// 1コンポーネントで利用しているモジュールをインポート
import { Component } from '@angular/core';

// 3コンポーネントに関する情報を宣言
@Component({
  selector: 'my-app',
  template: '<p>こんにちは、Angular 2!</p>'
})
// 2コンポーネントクラスを準備
export class AppComponent { }
リスト2 ルートコンポーネントAppComponentを定義するためのコード(app/app.component.ts)
  • 23は順番が逆になっているので注意すること。

 まず、1はコンポーネントを定義するためのAngular 2標準モジュールをインポートしています。

 コンポーネントの本体は2です。ここでは、先ほどAppModuleモジュールで指定したAppComponentという名前でコンポーネントクラスを作成しています。モジュールから参照できるよう、exportキーワードで外部に公開していることに注意してください。なお、本来であれば、classブロックの配下にコンポーネント固有のロジックを記述しますが、まずは空のままとしておきます。

 ただし、このままではコンポーネントとして動作することはできません。モジュールのときと同じく、コンポーネントの構成情報を@Componentデコレーターで定義しておきましょう(3)。Componentデコレーターでは、さまざまなパラメーターを指定できますが、ここで利用しているのは、以下の2個です*2

  • *2 その他のパラメーターについては、後日別稿で解説の予定です。
パラメーター名 概要
selector コンポーネントの適用先を表すセレクター式
template コンポーネントに適用するビュー(テンプレート)
表2 @Componengコンポーネントの主なパラメーター

 この例であれば、「<my-app>要素に対して、『<p>こんにちは、Angular 2!</p>』というテンプレートを適用」するためのAppComponentコンポーネントを定義したことになります。

[3]スタートアップコードを準備する

 ルートモジュールとルートコンポーネントを準備できたところで、これらを起動するためのスタートアップコードを準備します。

TypeScript
// 1アプリ起動に必要なモジュールをインポート
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

// 2モジュールを起動
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
リスト3 アプリを起動するためのコード(app/main.ts)

 まず、アプリ起動のために必要なモジュールをインポートします(1)。platformBrowserDynamicはブラウザーでアプリを起動するためのAngular 2標準モジュール、AppModuleは自分で作成したルートモジュールです(ルートコンポーネントはAppModule経由でインポートされますので、ここではインポート不要です)。

 必要なモジュールをインポートできたら、あとは、platformBrowserDynamic#bootstrapModuleメソッドでモジュールを起動します(2)。

[4]メインページを準備する

 最後に、アプリを動作するためのメインページを用意します。メインページは、(/appフォルダーではなく)アプリケーションルート直下に配置するものとします。

HTML
<html>
<head>
<title>Angular 2 TIPS</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--1Angular 2の動作に必要なライブラリをインポート -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!--2SystemJSを起動 -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<!--3ルートコンポーネントを呼び出し-->
<body>
<my-app>アプリをロード中です...</my-app>
</body>
</html>
リスト4 Angular 2アプリを動作するためのメインページ(index.html)

 まず、Angular 2アプリを動作させるためのライブラリをインポートします(1)。core-jsはレガシーなブラウザーのためのポリフィル(=足りない機能の穴埋め)、zone.jsreflect-metadataはAngular 2の動作に必要となるライブラリです。

 2ではSystemJSの設定情報(=systemjs.config.js前回の表1と表2を参照)を読み込むと共に、System.importメソッドで/appフォルダー配下のmain.ts(正しくはmain.js)を起動しています。main.jsが無条件に読み込まれるのは、設定ファイルsystemjs.config.jsで、以下のようにappモジュール配下のメインスクリプトとしてmain.jsがひも付けられているためです。

JSON
……前略……
packages: {
  app: {
    main: './main.js',
    defaultExtension: 'js'
  },
……後略……
リスト5 SystemJSによるメインスクリプトの定義(systemjs.config.js)

 そして、3がルートコンポーネントを表示するための領域です。これによって、先ほど@Componentデコレーターのセレクター指定(selectorパラメーター)に合致した要素(ここでは<my-app>要素)に対して、テンプレート(templateパラメーター)の内容が反映されます。

 <my-app>要素配下には、Angular 2が初期化される前に表示されるよう、一般的にはロード待ちのコンテンツを記載しておきます(コンポーネントが処理された後は、要素配下はテンプレートの内容で置き換えされます)。

[5]アプリを起動する

 以上でアプリを起動するための準備は完了です。コマンドプロンプトから以下のコマンドを実行してください。

コンソール
> npm start

> angular-quickstart@1.0.0 start C:\data\atips
> tsc && concurrently "tsc -w" "lite-server"

[1] Did not detect a `bs-config.json` or `bs-config.js` override file. Using lite-server defaults...
[1] ** browser-sync config **
[1] { injectChanges: false,
[1]   files: [ './**/*.{html,htm,css,js}' ],
[1]   watchOptions: { ignored: 'node_modules' },
[1]   server: { baseDir: './', middleware: [ [Function], [Function] ] } }
[0] 15:53:53 - Compilation complete. Watching for file changes.
[1] [BS] Access URLs:
[1]  ------------------------------------
[1]        Local: http://localhost:3000
[1]     External: http://192.168.1.7:3000
[1]  ------------------------------------
[1]           UI: http://localhost:3001
[1]  UI External: http://192.168.1.7:3001
[1]  ------------------------------------
[1] [BS] Serving files from: ./
[1] [BS] Watching files...
[1] 16.11.08 15:53:59 200 GET /index.html
[1] 16.11.08 15:53:59 200 GET /node_modules/zone.js/dist/zone.js
……後略……
リスト6 アプリを起動するためのコマンドと実行結果の例

 これによって、TypeScriptスクリプト(.tsファイル)がコンパイルされると共に、Angular 2標準の開発用サーバーlite-server)が起動して、以下のようにアプリが表示されます。この状態で、ソースコード(例えばindex.html)を書き換えると自動的にこれを認識して、ページがリロードされることも確認してみましょう。

図2 Angular 2アプリを実行した結果
図2 Angular 2アプリを実行した結果

[Note]npm startコマンド

 npm startコマンドは、package.jsonファイルで定義されたコマンドです。

JSON
"scripts": {
    "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
    "lite": "lite-server",
    ……中略……
},
リスト7 package.jsonでのコマンド定義

 ここでは、まずtscコマンドでTypeScriptスクリプトをコンパイルした後、tsc -wコマンドによる変更監視と、lite-serverコマンドによるサーバー起動を並列(concurrently)実行しなさい、という意味になります。

 以上、初めてのAngular 2アプリを実行できました。現時点でのアプリの構造を、以下にまとめておきます。

/atips …… アプリケーションルート
 ├─ /app*3
 │   ├─ main.ts …… スタートアップのためのスクリプト
 │   ├─ app.module.ts …… ルートモジュール
 │   └─ app.component.ts …… ルートコンポーネント
 ├─ /node_modules …… Angular 2で利用するライブラリ一式
 ├─ package.json …… npmの設定ファイル
 ├─ tsconfig.json …… TypeScriptコンパイラーの設定ファイル
 ├─ systemjs.config.js …… SystemJSの設定ファイル
 └─ index.html …… トップページ
図3 npm installコマンドを実行した後のアプリの構造
  • *3 サンプルを実行後であれば、.tsファイルと同名の.jsファイル(=コンパイル済みJavaScriptファイル)、.js.mapファイル(=マップファイル)もできているはずです。

 こうして見てみると、「簡単なアプリを動かすにもAngular 2は難しい!」と思われるかもしれません。しかし、ここまでの内容は、一般的なアプリではほぼ共通です。本稿のコードをスケルトンとして、以降のコードを追加していくようにすると、開発を効率化できるでしょう。

 本連載でも、以降、本稿のコードを前提として、そこからの差分を解説していきます。

処理対象:“Hello World” カテゴリ:基本
処理対象:ルートモジュール カテゴリ:基本
処理対象:ルートコンポーネント カテゴリ:基本
処理対象:main.ts カテゴリ:基本
API:NgModule カテゴリ:@angular > core > INTERFACE(インターフェース)|ADVANCED > Angular Modules
API:@NgModuleデコレーター カテゴリ:ADVANCED > Angular Modules
API:BrowserModule カテゴリ:@angular > platform-browser > CLASS(クラス)|ADVANCED > Angular Modules
API:@Component カテゴリ:@angular > core > Component decorator(コンポーネントデコレーター)
API:platformBrowserDynamic カテゴリ:@angular > core > platform-browser-dynamic > CONST(定数)
API:import|export  カテゴリ:TypeScript/JavaScript > 文法

※以下では、本稿の前後を合わせて5回分(第1回~第5回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

1. Angular 2を利用するには?(準備編)

人気のJavaScriptフレームワーク「Angular 2」の基本機能を目的別リファレンスの形式でまとめる連載スタート。まずはその特徴とインストール方法を説明する。

2. 【現在、表示中】≫ Angular 2を利用するには?(実装編)

初めてのAngular 2開発。誤解のしようもない最も基本的な“Hello World”を作成して、Angular 2アプリの基本構造を理解しよう。

3. コンポーネントに適用すべきテンプレートを指定するには?(template/templateUrlパラメーター)

@ComponentデコレーターのtemplateパラメーターやtemplateUrlパラメーターを使って、コンポーネントにテンプレート(ビュー)を適用する方法を説明する。

4. コンポーネントの値をビューに反映させるには?({{...}})

JavaScriptのオブジェクトをHTMLテンプレートに結び付けるためのデータバインドを記述するためのInterpolation記法の基礎を解説する。

5. ビューの中で「安全に」プロパティ/メソッドにアクセスするには?(「?.」演算子)

プロパティやメソッドを呼び出す際にレシーバーオブジェクトがnullでないことを確認した上で呼び出せる「?.」演算子の基本的な使い方を解説する。

イベント情報(メディアスポンサーです)

Twitterでつぶやこう!


Build Insider賛同企業・団体

Build Insiderは、以下の企業・団体の支援を受けて活動しています(募集概要)。

ゴールドレベル

  • 日本マイクロソフト株式会社
  • グレープシティ株式会社