この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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