HTML上のフォームの扱い
実際にデータを登録できるサービスの実装が終了したので、入力フォームを完成させます。
データを入力する場合にはHTMLのFORMを使いますが、AngularJSではFORMに特別な属性などをつけなくともデフォルトでngFormディレクティブが機能します。そのためデフォルトのFORMの動作と異なり、最初は多少戸惑うかもしれませんが、これはシングルページアプリケーションを作成する際には通常よりも便利に機能します。
シングルページアプリケーションでは、GETやPOSTなどでのリクエストURLでのページの遷移をしてしまっては、内部で管理しているデータが消えてしまいますので都合が悪いです。このために、フォームでのリクエスト処理がデフォルトで無効になっています。また、HTML5にあるデフォルトのフォームの入力要素での入力チェックに対しても、より強化された機能を提供しています。
HTMLフォームの作成
リスト4は、サンプルアプリケーションでのタスクの追加するためのHTMLの抜粋です。
<!--(1)name属性でフォームを識別する --> <form role="form" name="addItemForm" ng-controller="addController"> <!--(2)フォームの$valid変数でフォーム全体のチェックが可能 --> <div ng-show="!addItemForm.$valid"> <div class="alert alert-warning" role="alert">必須項目を入力してください</div> </div> <div class="form-group"> <label>件名(*)</label> <!--(3)requiredなどの属性でinputでの入力をチェックできる。また、ng-modelでデータバインディングする --> <input type="text" class="form-control" placeholder="タスク名を入力" required="" ng-model="item.title"> </div> <div class="form-group"> <label>メモ(*)</label> <textarea class="form-control" placeholder="タスク名を入力" ng-model="item.memo"></textarea> </div> <button type="button" class="btn btn-primary btn-block" ng-click="addItem()">追加</button> </form>
フォームはname属性を指定します(1)。
また(2)のように先ほど指定したname属性での値のオブジェクトが作成され、$validプロパティが存在しますのでフォーム全体の有効性をチェックができます。また、各inputやselect要素にも同様に$validプロパティが存在し、個別の要素毎にも確認ができます。そのチェックは、required属性などを使って入力必須制約をつける事ができます(3)。
入力制約には他にも文字数があり、要素ごとに指定可能な制約についてはAPIドキュメントで確認ができます。また、各要素のデータをコントローラとのデータバインディングするためには、ng-model属性を使います。
コントローラ側でのフォームへのアクセス
コントローラ側でフォームにアクセスする際には、変数をあらかじめ用意することなく、form要素のname属性名を利用してアクセスが可能です。リスト5はデータの追加を行うコントローラ側のサンプルコードの抜粋です。
module.controller('addController',function($scope,Items){ //(1)初期データ(すべて空データとする) $scope.item = {}; $scope.addItem = function(){ if(!$scope.addItemForm.$valid) { //(2)フォームの$valid変数の利用 alert('入力エラーです'); return; } Items.add($scope.item,function(data){ //(3)$scope.itemにはtitleとmemoプロパティが設定されている // : 省略 $scope.item = {}; //(4)登録後に再度、データをクリア }); } });
(1)では、テンプレート側とng-model属性にてバインディングされた要素の値をすべてクリアします。(2)のようにHTMLフォームで利用した$valid変数もそのまま利用ができます。また、入力済みの場合には(3)のように自動的にng-modelで指定した変数に値が設定されています。したがって、そのデータをそのまま使って実際に先ほど作成したItemsサービスのaddメソッドを使ってデータを登録することができます。また、成功した後には、再度、(4)のようにデータをクリアします。
最後に
AngularJSはHTMLのテンプレート機能やデータバインディングの便利さが目立ってしまいますが、DI機能も非常に便利な機能です。
今回紹介したサービス機能は、DI機能を使って疎結合に保ったままアプリケーションを作ることができます。次回は、この疎結合の特性を使ってデータをサーバで管理するサービスに変更します。