サイトトップ

Director Flash 書籍 業務内容 プロフィール

HTML5テクニカルノート

AngularJS: コンポーネントを使う


AngularJSは、アプリケーションをコンポーネントに分けて、構造化することができます。コンポーネントはAngular 2にも採り入れられている仕組みで、大きなアプリケーションでもコンポーネントを単位として組み立てれば、開発が柔軟に進められます。本稿では、簡単なデータバインディングのサンプルを、コンポーネントが使われた構成に書き替えてみます。

01 コントローラに定めた値をデータバインディングでHTMLドキュメントに表示する

まずは、コンポーネントは使わずに、コントローラに定めた値を、データバインディングでHTMLドキュメントに表示してみましょう(「AngularJS入門 03: コントローラで値を与える」参照)。HTMLドキュメントには、本稿執筆時で最新のAngularJS 1.5.5を読み込みます。


<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>

<body>要素にはつぎのようにng-appディレクティブを定め(モジュールheroineApp)、<div>要素にはng-controllerディレクティブでコントローラ(mainCtrl)を加えました。そして、<span>要素が{{ }}によりデータバインディングしたコントローラの値(heroine.name)を取り出して表示します。


<body ng-app="heroineApp">
<div ng-controller="mainCtrl as ctrl">
	<h4>ヒロイン</h4>
	<span>名前: {{ctrl.heroine.name}}</span>
</div>
</body>

ng-appディレクティブに与えるモジュール(heroineApp)とコントローラ(mainCtrl)は、以下のコード001のように定めます。すると、コントローラに定めた値(heroine.name)が、HTMLドキュメントの<span>要素にデータバインディングで示されます(図001)。

図001■コントローラの値がデータバインディングで表示された

図001

コード001■コントローラにプロパティ値を定める


angular.module('heroineApp', [])
.controller('mainCtrl', function() {
	this.heroine = {
		name: 'シータ'
	};
});

02 アプリケーションからコンポーネントを切り分ける

つぎに、前項01のサンプルからコンポーネントを切り分けてみましょう。データバインディングした<span>要素の機能をコンポーネントにします。コンポーネントには小文字で始まり単語の頭を大文字にした(「キャメル記法」)名前をつけます(たとえば、"heroineDetail")。この名前をディレクティブと同じすべて小文字のハイフン"-"つなぎ(「チェインケース」)にして(たとえば'heroine-detail')、つぎのようにHTMLに要素のかたちで差し込めます。


<div ng-controller="mainCtrl as ctrl">
	<h4>ヒロイン</h4>
	<!--<span>名前: {{ctrl.heroine.name}}</span>-->
	<heroine-detail heroine="ctrl.heroine"></heroine-detail>
</div>

コンポーネントはJavaScriptファイルに定め、差し込むHTMLコードもつぎのような別のHTMLドキュメントをテンプレートとして用いることができます。名前はともにコントローラ(heroineDetail)と揃えるのがわかりやすいでしょう。コンポーネントは、デフォルトでは$ctrlで参照します[*001]


// heroineDetail.html
<span>名前: {{$ctrl.heroine.name}}</span>

コンポーネントはJavaScriptコードにangular.Module.component()メソッドで、つぎのように定めます。第1引数はコンポーネント名の文字列で、第2引数にオブジェクトでオプションを定義します。

component(コンポーネントの名前, ディレクティブ定義オブジェクト)

今回は以下のコード002のJavaScriptファイル(heroineDetail.js)のとおり、第2引数のオプションにはつぎの表001の3つのプロパティを与えました。templateUrlプロパティは、前述のテンプレートにするHTMLドキュメントのURLを示す文字列です。controllerプロパティには、コントローラのコンストラクタ関数(HeroineDetailController)を渡します。今回はオブジェクト(heroine)をデータバインディングするだけですので、コンストラクタ関数の本体は空で構いません。bindingsプロパティには、バインディングするオブジェクト名に親子コンポーネント間のデータバインディングを示す値として文字列=を与えます。

表001■ディレクティブ定義オブジェクトのプロパティ

プロパティ 説明
templateUrl 読み込むテンプレートのURLを示す文字列。
controller コントローラのコンストラクタ関数。
bindings データバインディングするプロパティとその仕方を定めるオブジェクト。

コード002には、コンポーネントのテンプレートにするHTMLドキュメント(heroineDetail.html)と、メインのHTMLに加えた<script>および<body>要素の記述もまとめました。これで、コントローラ(mainCtrl)に定めたオブジェクト(heroine)がコンポーネント(heroineDetail)にデータバインディングされ、HTMLドキュメントに差し込まれたテンプレートの要素の中に値(heroine.name)が示されます。サンプル001はフレーム内でその結果を示しています。

コード002■コントローラに定めたオブジェクトの値をコンポーネントで差し込んだテンプレートにデータバインディングする

heroineDetail.js

angular.module('heroineApp')
.component('heroineDetail', {
	templateUrl: 'heroineDetail.html',
	controller: HeroineDetailController,
	bindings: {
		heroine: '='
	}
});
function HeroineDetailController() {}

heroineDetail.html

<span>名前: {{$ctrl.heroine.name}}</span>

<script>要素

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script>
angular.module('heroineApp', [])
.controller('mainCtrl', function() {
	this.heroine = {
		name: 'シータ'
	};
});
</script>
<script src="heroineDetail.js"></script>

<body>要素

<body ng-app="heroineApp">
<div ng-controller="mainCtrl as ctrl">
	<h4>ヒロイン</h4>
	<heroine-detail heroine="ctrl.heroine"></heroine-detail>
</div>
</body>

サンプル001■コントローラに定めたオブジェクトの値がコンポーネントで差し込んだテンプレートにデータバインディングで示された

[*001] コンポーネントのコントローラは、controllerAsに定める識別子で参照できます。そのデフォルト値が$ctrlとされています(「その使い方はもう古いかも?AngularJS老化チェック(ディレクティブ篇)」および「feat(component): default controllerAs to be $ctrl」参照)。


作成者: 野中文雄
作成日: 2016年5月12日


Copyright © 2001-2016 Fumio Nonaka.  All rights reserved.