サイトトップ

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

HTML5テクニカルノート

AngularJS入門 03: コントローラで値を与える


AngularJSは、JavaScriptコードで定めたコントローラにより、データの扱いを定めることができます。本稿では、はじめの一歩として、コントローラで初期値をHTMLドキュメントに与えてみます。

01 データバインディングでテキストとスタイルが変わるフォーム

本稿で手を加えるのは、「AngularJS入門 02: 要素の属性を動的に変える」でデータバインディングのサンプルとして書いたコード002です。入力フィールドに書いたテキストがチェックボックスの右に表示され、チェックするとテキストに取り消し線が引かれます(図001)。この入力フィールドに加えるテキストと、チェックボックスのオン・オフの初期値を、JavaScriptコードで書くコントローラに定めてみましょう。

図001■データバインディングでテキストとスタイルが変わる

図001左 図001右

02 JavaScriptでコントローラを定める

AngularJSのコントローラは、モジュールに定めます。そのモジュールを得るのがangular.module()関数です。第1引数にはモジュールの名前の文字列、第2引数は必要なモジュールの名前の文字列がエレメントに納められた配列を渡します。今回はとくにないので、配列は空にします。


angular.module(名前, [])

コントローラは、angular.module()関数が返すオブジェクト(angular.Module)に、controller()メソッドで加えます。第1引数はやはり文字列でコントローラの名前、第2引数には初期化のコンストラクタ関数を渡します。


Moduleオブジェクト.controller(名前, コンストラクタ関数)

<script>要素に、JavaScriptコードをつぎのように書き加えます。controller()メソッドの関数本体でthis参照に定めたオブジェクト(todo)が、AngularJSで扱うHTMLドキュメントの中から参照できます。オブジェクトにはふたつのプロパティ(textとdone)を与えました。


var myApp = angular.module('todoApp', []);
myApp.controller('TodoListController', function() {
	this.todo = {text: 'AngularJSを学ぶ', done: true};
});

03 モジュールとコントローラをHTMLドキュメントに定める

JavaScriptコードで定めたモジュールとコントローラは、HTMLドキュメントにディレクティブで加えます。まず、モジュール名("todoApp")は、ng-appディレクティブにつぎのように値として与えます。


<html ng-app="todoApp">

つぎに、扱う対象となる親要素にng-controllerディレクティブで、コントローラ名を与えます。このとき、asの後に定めるプロパティ名を参照すると、コントローラのコンストラクタ関数で定めたプロパティが取り出せます。


ng-controller="コントローラ名 as プロパティ名"

ng-controllerディレクティブは、つぎのように<div>要素に加えました。ng-modelディレクティプや{{ }}に与える値は、ng-controllerディレクティブのasで定めたプロパティ(todoList)の参照から得ています。


<div ng-controller="TodoListController as todoList">
	<ul class="list-unstyled">
		<li>
			<input type="checkbox" ng-model="todoList.todo.done">
			<span class="done-{{todoList.todo.done}}">{{todoList.todo.text}}</span>
		</li>
	</ul>
	<form>
		<input type="text" ng-model="todoList.todo.text" size="30" placeholder="add a todo here">
	</form>
</div>

これで、コントローラ(TodoListController)からテキストとチェックボックスの初期値(todo.textとtodo.done)が与えられます(図002)。テキストの表示やスタイルのデータバインディングは、もとのまま残っています。HTMLドキュメントとJavaScriptの中身は、以下のコード001にまとめました。また、サンプル001としてファイルをフレームに掲げます。

図002■コントローラで初期値が与えられる

図002

コード001■コントローラでフォームに初期値を与える


<html ng-app="todoApp">


var myApp = angular.module('todoApp', []);
myApp.controller('TodoListController', function() {
	this.todo = {text: 'AngularJSを学ぶ', done: true};
});


<div class="container">
	<h2>Todo</h2>
	<div ng-controller="TodoListController as todoList">
		<ul class="list-unstyled">
			<li>
				<input type="checkbox" ng-model="todoList.todo.done">
				<span class="done-{{todoList.todo.done}}">{{todoList.todo.text}}</span>
			</li>
		</ul>
		<form>
			<input type="text" ng-model="todoList.todo.text" size="30" placeholder="add a todo here">
		</form>
	</div>
</div>

サンプル001■コントローラでフォームに初期値を与える

04 DOMの参照を$scopeデータプロパティで定める

これまでのAngularJS(1.2まで)はng-controllerディレクティブでasは使わず、$scopeデータプロパティでDOMの参照を定めていました。このプロパティを用いると、前掲コード001はつぎのコード002のように書き替えられます。AngularJS 1のサンプルはこの書き方をしたものが多く見受けられます。けれど、Angular 2では$scopeプロパティが使えなくなりますので、thisキーワードとasで参照をやり取りすることに慣れておいた方がよいでしょう。

コード002■コントローラで$scopeプロパティに定めた初期値をフォームに与える


var myApp = angular.module('todoApp', []);
// myApp.controller('TodoListController', function() {
myApp.controller('TodoListController', function($scope) {
	// this.todo = {text: 'AngularJSを学ぶ', done: true};
	$scope.todo = {text: 'AngularJSを学ぶ', done: true};
});


<!--<div ng-controller="TodoListController as todoList">-->
<div ng-controller="TodoListController">
	<ul class="list-unstyled">
		<li>
			<!--<input type="checkbox" ng-model="todoList.todo.done">-->
			<input type="checkbox" ng-model="todo.done">
			<!--<span class="done-{{todoList.todo.done}}">{{todoList.todo.text}}</span>-->
			<span class="done-{{todo.done}}">{{todo.text}}</span>
		</li>
	</ul>
	<form>
		<!--<input type="text" ng-model="todoList.todo.text" size="30" placeholder="add a todo here">-->
		<input type="text" ng-model="todo.text" size="30" placeholder="add a todo here">
	</form>
</div>


作成者: 野中文雄
更新日: 2016年3月31日 AngularJS 1.5.3のリリースにともない、本文とコードを更新。
作成日: 2016年2月3日


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