AngularJSのサービス#AngularJS入門その5
AngularJSのサービス
AngularJSにおけるサービスとは、アプリにおいて任意のタスクを実行する関数として使用されます。 例えば、AngularJSではajax通信用に$http組み込みサービスを持っています。 もちろん、サービスを自分で定義して使用することも可能です。
AngularJSでビジネスロジックはサービスとして実装されることが推奨されているため、 独自サービスを作成する機会は多いと思います。 その独自サービスをAngularJSで作成するには複数の方法があるので、それらの方法を確認してみましょう。
今回使用した動作環境は以下のとおりです。 なお、本記事で紹介しているコードは、以前作成したangular-seedを使って動作を確認しました。
- OS : MacOS X 10.9.2
- node.js : 0.10.24
- Git : 1.8.5.2
サービスを使う
AngularJSで独自定義のサービスを使用するには、Module#factoryを使用するか、 自分でモジュールconfig関数内部で$provideを使用してサービスを登録する必要があります。 また、すべてのサービスは前回解説したDIの仕組みを使用して登録することになります。
サービスを登録してみる
サービスを登録するには、そのサービスが全体の一部となるモジュールを持つようにします。 すると、モジュール用APIかconfig関数内の$provideサービスを使用してサービスを登録することができます。
//angular.Moduleを使用してサービス登録 var myModule = angular.module('myModule', []); myModule.factory('myServiceId', function() { var myServiceInstance; /** *myServiceInstanceを作成. *ここでfactory関数を記述する */ return myServiceInstance; }); //$provideサービスを使用してサービス登録 angular.module('myModule', [], function($provide) { $provide.factory('myServiceId', function() { var myServiceInstance; /** *myServiceInstanceを作成. *ここでfactory関数を記述する */ return myServiceInstance; }); });
サービスのインスタンスが登録されるわけではなく、サービスを作成するファクトリー関数が登録されます。
サービスの持つ機能
・依存性 サービスには依存性を指定することが可能です。ファクトリ関数の引数として指定すれば依存性を指定できます。 次の例は、AngularJS組み込みの$windowサービスに依存した関数を作成しています。 $windowサービスはfactoryによってファクトリー関数によってstackMessagesへ引数として引き渡されます。
//stackMessagesは受け取ったメッセージをスタックし、3つになったらアラート表示する angular.module('myModule', [], function($provide) { $provide.factory('stackMessages', ['$window', function(win) { var msgArray = []; return function(msg) { msgArray.push(msg); if (msgs.length == 3) { win.alert(msgArray.join("")); msgArray = []; } }; }]); });
・サービスはシングルトン AngularJSにおけるサービスは全てシングルトンになります。 インジェクター毎に与えられるサービスのインスタンスは、常に1つです。
・Angularサービスのインスタンス化 AngularJSの全てのサービスは、遅延してインスタンス化されます。そのため、サービスは必要になったときに AngularJSによってインスタンス化されます。
コントローラでサービスを使う
サービスは、以前解説したAngularJSのコントローラへDIしてよく使用されます。 DIされるサービス名の文字列を含んだ配列の$injectプロパティを使用してサービス名を指定することが可能です。 サービス名は、AngularJSで登録されたサービスのIDと同じにしておく必要があります。 配列内のサービスの順番は、ファクトリー関数を呼び出す際に使用されます。
では公式ドキュメントサイトにある例を参考に、 コントローラとサービスを連携させたサンプルをつくってみます。 angular-seed/app/jsディレクトリにsample1.jsファイルを作成しましょう。
angular. module('MyServiceModule', []). factory('stackMessage', ['$window', function(win) { var msgs = []; return function(msg) { msgs.push(msg); if (msgs.length == 3) { win.alert(msgs.join("\n")); msgs = []; } }; }]); function myController(scope, notifyService) { scope.stackMessage = function(msg) { notifyService(msg); }; } myController.$inject = ['$scope','stackMessage'];
MyServiceModuleでstackMessageサービス(関数)を作成し、myControllerにDIしています。 上記サービスとコントローラを使用するhtmlもappディレクトリにsample1.htmlという名前で作成します。
<!doctype html> <html ng-app="MyServiceModule"> <head> <script src="http://code.angularjs.org/1.2.3/angular.min.js"></script> <script src="js/sample1.js"></script> </head> <body> <div ng-controller="myController"> <p>Let's try this simple notify service, injected into the controller...</p> <input ng-init="message='test'" ng-model="message" > <button ng-click="callNotify(message);">NOTIFY</button> <p>(you have to click 3 times to see an alert)</p> </div> </body> </html>
ではサーバを起動し、ブラウザでアクセスしてみましょう。
% cd /path/your/angular-seed % node scripts/web-server.js Http Server running at http://localhost:8000/
http://localhost:8000/app/sample1.htmlにアクセスして動作を確認してみてください。
まとめ
今回は基本的なサービスの使い方について解説しました。 サービスの具体的な使い分け方についてはこちらもご確認ください。
参考サイトなど
- AngularJS公式: http://angularjs.org/
- angular-seed: https://github.com/angular/angular-seed
- 本blogでAngularJSタグのついた記事: https://dev.classmethod.jp/tag/angularjs/
- AngularJSのサービスについて : http://js.studio-kingdom.com/angularjs/guide/understanding_services