「AngularJS」の便利な機能

こんにちは。キャスレーコンサルティングのSD(システム・デザイン)事業部の三橋です。
今回は、「AngularJS」というJSフレームワークの機能についてご紹介させていただきます。

初めてAngularJSで開発した際にかなり苦戦した覚えがありますので、
これからAngularJSに触れる方のお役に立てば幸いです。

・公式サイト
AngularJS

ディレクティブについて

AngularJSでは、HTMLに対して独自の要素/属性を追加することができます。
これらのカスタム要素/属性がディレクティブです。

後述する双方向データバインディングについても、「ng-model」というディレクティブを使用して実現しています。
AngularJS標準で多くのディレクティブが提供されていますが、
それらでは必要な要件を満たせない場合、ディレクティブを自作することができます。
ディレクティブの自作に関しての詳細は、弊社技術ブログにて執筆している方がおりますので、そちらをご参照ください。

「AngularJS」の特徴紹介と考察

標準で提供されているディレクティブを把握しきれておらず、無駄に自作をしてしまうこともあるかと思います。
本格的なアプリを開発する際は、AngularJSの公式リファレンスなどに目を通しておきましょう。

双方向データバインディングについて

データバインディングとは、モデルとビューを結びつける仕組みのことです。
AngularJSのデータバインディングは、これを双方向に行います。

ビューの変更をモデルに、モデルの変更をビューに同期してくれるため、
開発者がビューの変更を、モデルに反映させる必要がなくなるのです。
サンプルコードを以下に記載します。

bind.html

<!doctype html>
<html ng-app="bindApp" >
<head>
  <meta charset="utf-8">
  <title>双方向データバインディング</title>
  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.4.1%2Fangular.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22.%2Fbind.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
</head>
<body ng-controller="bindController">
  
<form>
    <label for="inputString">input:</label>
    <input id="inputString" type="text" ng-model="outputString" />
    
<div>output:{{outputString}}</div>

  </form>

</body>
</html>

bind.js

angular.module('bindApp', [])
	.controller('bindController', ['$scope', function($scope){
		$scope.outputString = 'test';
	}]);

resurt01

入力したテキストをラベルに出力するだけの簡単なソースですが、
これだけでも、双方向データバインディングの便利さは伝わると思います。

双方向データバインディングならば、他のJSフレームワークにも存在しますが、
AngularJSのそれは、非常にシンプルに記述することができます。

例えば、上記のサンプルコードですが、双方向データバインディングを動かすだけなら、

bind.html

<!doctype html>
<html ng-app>
<head>
  <meta charset="utf-8">
  <title>双方向データバインディング</title>
  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.4.1%2Fangular.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
</head>
<body>
  
<form>
    <label>input:</label>
    <input type="text" ng-model="outputString" />
    
<div>output:{{outputString}}</div>

  </form>

</body>
</html>

これだけで良いのです。
javascriptの記述は、一切必要ありません。
このシンプルさは、双方向データバインディング機能を有する他のJSフレームワークに比べ、
AngularJSが勝っている特徴と言えます。

双方向データバインディングとパフォーマンスについて

モデルを監視し、変更があった際はビューに反映する処理が常に動き続けているのなら、
データバインディングの使用数増加に伴い、パフォーマンスに悪影響を与えるのでは?
と考える方もいらっしゃるかもしれませんが、AngularJSにはそれを回避するための機能も存在します。
それが、One-time Binding(ワンタイムバインディング)という機能です。

これは対象がundefinedの間だけ監視し、一度値をバインドしたら監視を止める機能です。
これにより、監視し続けることはなくなります。
使い方も非常に簡単です。


<form>
    <label for="inputString">input:</label>
    <input id="inputString" type="text" ng-model="::outputString" />
    
<div>output-normal:{{outputString}}</div>

    
<div>output-onetime:{{::outputString}}</div>

</form>

onetime01

onetime02

テキストボックスとバインドされている、output-onetimeのoutputStringにコロンが2つ記述されています。
実行結果から、output-normalはテキストの変更に応じて表示が変わりますが、
output-onetimeの方は最初だけテキストの内容が反映され、次の変更は反映されていないことがわかります。
これだけで問題解決です。

といっても、バインディングがパフォーマンス低下の原因であったのは、
初期のころのお話で、現在はかなり改善されているため、
このOne-time Bindingを使用することはなくなってきたようです。
そのため、おまけ程度の認識で良いと思います。

DIコンテナーについて

DI(Dependency Injection)コンテナーとは、
オブジェクトが動作するために、必要なオブジェクトを外部から引き渡すための仕組みです。
使い方自体はシンプルで分かりやすいです。

実は、上記の双方向データバインディングのサンプルコードでもDIコンテナーを使用していました。

bind.js

angular.module('bindApp', [])
	.controller('bindController', ['$scope', function($scope){
		$scope.outputString = 'test';
	}]);

このサンプルでは、$scopeをコントローラーに引き渡しています。
これだけでAngularJSでは、オブジェクト同士の依存関係を設定できます。
実際に、AngularJSで開発を行う際は、よく使う機能ですので、是非覚えておきましょう。

まとめ

AngularJSの便利な機能を紹介してきました。
すべてを紹介しきることはできませんでしたが、AngularJSの便利さと機能の豊富さはお伝えできたと思います。

AngularJSの最大の特徴は、その多機能性にあります。
反面、多機能すぎるがゆえの学習コストの高さというデメリットを抱えているのも事実です。
その為、AngularJSは機能が豊富でなんでもできるからとりあえずこれを使おう!的な考えで採用すると、
なかなか大変な思いをすることになるかもしれません。

実際に開発に使用した感想としては、
やはり、学習コストが負荷になりました。
しかし、「こういうことがやりたい」という時に調べれば大抵AngularJSの機能でカバーしてくれていたので、
学べば学ぶほどできることの幅が広がっていくところは、豊富な機能を売りにしているだけはあります。

しかし、AngularJSは多機能ゆえに多くの状況に対応できる反面、
AngularJSのルールから外れた実装をしようとすると、かなり大変です。
複雑なシステムよりはシンプルなアプリケーションでの開発で、
力を発揮するフレームワークというのは良く言われていますが、
シンプルなコードをよりコンパクトに実装できるというのは実際に開発をしながら感じていました。

一言にまとめれば、
「AngularJSとは要件に応じて選択してあげれば、確かな生産性を約束してくれる優秀なフレームワーク」です。