虽然AngularJS提过了很多有用的服务,但是如果你要创建一个很棒的应用,你可能还是要写自己的服务。你可以通过在模块中注册一个服务工场函数,或者通过Modeul#factory api或者直接通过模块配置函数中的$provide api来实现。
所有的服务都符合依赖注入的原则。它们用一个唯一的名字将自己注册进AngularJS的依赖注入系统(injector),并且声明需要提供给工场函数的依赖。它们的依赖在测试中可以是虚拟的,这使得它们能很好地被测试。formatDate
注册服务
要注册服务,你首先要有一个包含该服务的模块。然后你就能通过模块的api或者使用模块配置函数中的$provide服务来注册你的服务了。下面的伪代码显示了这两种方法。
使用angular.Module api:
var myModule = angular.module('myModule', []); myModule.factory('serviceId', function() { var shinyNewServiceInstance; //factory function body that constructs shinyNewServiceInstance return shinyNewServiceInstance; });
使用$provide服务:
ngular.module('myModule', [], function($provide) { $provide.factory('serviceId', function() { var shinyNewServiceInstance; //factory function body that constructs shinyNewServiceInstance return shinyNewServiceInstance; }); });
依赖
服务不仅可以被依赖,还可以有自己的依赖。依赖可以在工场函数的参数中指定。参阅AngularJS的依赖注入系统,和使用依赖的数组表示法和$inject属性来让依赖表示精简化。
下面是一个很简单的服务的例子。这个服务依赖于$window服务(会被当成参数传递给工场函数),并且只是个函数。这个服务的任务是存储所有的通知;在第三个通知以后,服务会用window的alert来输出所有的通知
angular.module('myModule', [], function($provide) { $provide.factory('notify', ['$window', function(win) { var msgs = []; return function(msg) { msgs.push(msg); if (msgs.length == 3) { win.alert(msgs.join("\n")); msgs = []; } }; }]);
实例化AngularJS的服务
所有服务都是延迟实例化的。这意味着所有的服务只有在需要时,或者被依赖时才会实例化。换句话说,AngularJS不会实例化服务,除非被要请求了或者被应用直接或间接依赖了。
作为单例的服务
最好,要注意的是所有AngularJS服务都是单例的。这意味着在每一个注入器中都只有一个需要的服务的实例。因为AngularJS极度讨厌全局的东西,所以是可以创建多个注入器的,并且每个住一起有自己的服务实例。但这种情况很少,除非在测试中,这样的特性才极度重要。
一个简单的例子:
<!DOCTYPE html> <html lang="en" ng-app="ionicServiceApp"> <head> <meta charset="UTF-8"> <title>注册自己的service</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <meta id="viewport" name="viewport" content="width=320,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/> <meta name="apple-mobile-web-app-capable" content="yes"/> <meta name="apple-mobile-web-app-status-bar-style" content="black"/> <meta content="telephone=no" name="format-detection"/> <title>PoPoverTest</title> <link rel="stylesheet" href="../../Ionic/css/ionic.min.css"/> <script src="../../Ionic/js/ionic.bundle.min.js"></script> <script> var app = angular.module("ionicServiceApp", ['ionic'], function ($provide) { $provide.factory("notify", ["$window", "$timeout","$http", function (win, timeout,$http) { return { attribute: function (msg) { return $http.get('/api/user'); } } }]) }); app.controller('serviceCtrl', ['$scope', '$log','$window', 'notify', function ($scope, $log,win, notify) { $scope.data=notify.attribute("21").success(function(data,status){ $log.log(data); }).error(function(data,status){ win.alert(data); }); $log.log("34432"); }]); </script> </head> <body> <div ng-controller="serviceCtrl"> </div> </body> </html>