代码改变世界

angularjs服务

2017-08-15 16:06  蝶梦中  阅读(137)  评论(0编辑  收藏  举报

Angular服务是使用依赖注入绑定的可替换的对象。你可以使用服务来在你的程序间组织和共享代码。

Angular服务是:

  • 懒实例化:Angularjs只有在一个应用依赖该服务时对其进行实例化。
  • 单例对象:每个依赖服务的组件得到一个服务工厂生成的单一实例引用

Angularjs提供了一些很有用的服务(如$http),不过对于很多程序来说,你仍然需要创建自定义的服务。

注意:就像其他核心的AngularJS标识符一样,内嵌的服务使用$作为开始字符。

使用一个服务

为了使用一个AngularJS服务,你只需要添加依赖关系到依赖服务的组件上(控制器,服务,过滤器或是指令)。AngularJS的依赖注入系统会完成剩下的工作。

index.html

<div id="simple" 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>

 

script.js

angular.
 module('myServiceModule', []).
  controller('MyController', ['$scope','notify', function ($scope, notify) {
    $scope.callNotify = function(msg) {
      notify(msg);
    };
  }]).
 factory('notify', ['$window', function(win) {
    var msgs = [];
    return function(msg) {
      msgs.push(msg);
      if (msgs.length == 3) {
        win.alert(msgs.join("\n"));
        msgs = [];
      }
    };
  }]);

 

创建服务

程序开发者可以在AngularJS模块中通过注册服务的名字和服务工厂函数来自由的定义他们独有的服务。

服务工程函数生成在程序的其他部分代表服务的单独的对象或函数。服务返回这个对象或函数会被注入到其他任意模块(控制器,服务,过滤器或是指令)来指定对服务的依赖。

注册服务

服务通过module API注册到modules。下面是一个常用的例子:

var myModule = angular.module('myModule', []);
myModule.factory('serviceId', function() {
  var shinyNewServiceInstance;
  // factory function body that constructs shinyNewServiceInstance
  return shinyNewServiceInstance;
});

 

请注意你并没有注册一个服务实例而是注册了一个工厂函数,当调用该函数时会创建这个实例。

依赖性

服务可以拥有其独有的依赖性。就像在控制器中声明依赖关系一样,你可以在服务工厂函数中为具体的变量生命依赖关系。

在下面的例子中模块拥有两个服务,每个都有各种依赖关系。

var batchModule = angular.module('batchModule', []);

/**
 * The `batchLog` service allows for messages to be queued in memory and flushed
 * to the console.log every 50 seconds.
 *
 * @param {*} message Message to be logged.
 */
batchModule.factory('batchLog', ['$interval', '$log', function($interval, $log) {
  var messageQueue = [];

  function log() {
    if (messageQueue.length) {
      $log.log('batchLog messages: ', messageQueue);
      messageQueue = [];
    }
  }

  // start periodic checking
  $interval(log, 50000);

  return function(message) {
    messageQueue.push(message);
  }
}]);

/**
 * `routeTemplateMonitor` monitors each `$route` change and logs the current
 * template via the `batchLog` service.
 */
batchModule.factory('routeTemplateMonitor', ['$route', 'batchLog', '$rootScope',
  function($route, batchLog, $rootScope) {
    return {
      startMonitoring: function() {
        $rootScope.$on('$routeChangeSuccess', function() {
          batchLog($route.current ? $route.current.template : null);
        });
      }
    };
  }]);

 

在这个例子中,请注意:

  • batchlog服务依赖于系统自带的$interval和$log服务
  • routeTemplateMonitor服务基于内嵌服务$route和我们的自定义服务batchlog。
  • 所有的服务都可以使用数组表示法来声明依赖性。
  • 数组里标识符的顺序跟工厂函数里参数名称的顺序相同。

使用$provide注册服务

你可以通过使用config函数里面的$provide服务来注册服务。

angular.module('myModule', []).config(['$provide', function($provide) {
  $provide.factory('serviceId', function() {
    var shinyNewServiceInstance;
    // factory function body that constructs shinyNewServiceInstance
    return shinyNewServiceInstance;
  });
}]);

 

这个功能经常被用在单元测试中来测试一个服务的依赖性。