AngularJS服务

AngularJS服务概念:

AngularJS services are substitutable objects that are wired together using dependency injection (DI). You can use services to organize and share code across your app.javascript

AngularJS服务是使用依赖注入(DI)链接在一块儿的可替换对象。您可使用服务在整个应用中组织和共享代码。html

  • 在 AngularJS 中,服务是一个函数或对象,可在你的 AngularJS 应用中使用。
  • 服务提供了一种能在应用的整个生命周期内保持数据的方法,它可以在控制器之间进行通讯,并保持数据的一致性。

AngularJS服务包括:

  • 懒实例:当一个组件依赖它的时候,AngularJS只是实例化了一个服务
  • 单例:依赖于服务的每一个组件都会得到对服务工厂生成的单个实例的引用。
    • 服务是一个单例对象,在每一个应用中只会被实例化一次(被$injector)

AngularJS 提供了好多有用的服务,像$http,可是对于大多数的应用程度,你须要建立你自已的服务。java

Note: Like other core AngularJS identifiers, built-in services always start with $ (e.g. $http). 
复制代码

像其余核心AngularJS标识符同样,建立服务一般须要用到(例如:http)angularjs

使用服务:

To use an AngularJS service, you add it as a dependency for the component (controller, service, filter or directive) that depends on the service. AngularJS's dependency injection subsystem takes care of the rest.数组

为了使用AngularJS服务,请将其添加为依赖于服务的组件(控制器,服务,过滤器或指令)的依赖项。AngularJS的依赖注入子系统负责其他部分。bash

使用内建服务

AngularJS 内建了30 多个服务。有个 $location 服务,它能够返回当前页面的 URL 地址。app

<!DOCTYPE html>
<html ng-app="app">
<head lang="zh_CN">
    <meta charset="utf-8">
    <title>Angular服务学习</title>
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js" type="text/javascript"></script>
</head>
<body>
<div ng-controller="ctrl">
    <p>当前页面的Url:</p>
    <h3>{{myUrl}}</h3>
</div>
</body>
<script>
    let app = angular.module('app', []);
    app.controller('ctrl', function ($scope, $location) {
        $scope.myUrl = $location.absUrl();
    })
</script>
</html>
复制代码

注意 $location 服务是做为一个参数传递到 controller 中。若是要使用它,须要在 controller 中定义。ide

使用自定义服务

<!DOCTYPE html>
<html ng-app="app">
<head lang="zh_CN">
    <meta charset="utf-8">
    <title>Angular服务学习</title>
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js" type="text/javascript"></script>
</head>
<body>
<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> </body> <script> let app = angular.module('app', []); app.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 = []; } }; }]); </script> </html> 复制代码

建立服务

建立服务的三种方式:函数

  1. factory服务
  2. $provide服务

Application developers are free to define their own services by registering the service's name and service factory function, with an AngularJS module.单元测试

应用程序开发人员能够经过使用AngularJS模块注册服务的名称和服务工厂函数来自由定义本身的服务 。

The service factory function generates the single object or function that represents the service to the rest of the application. The object or function returned by the service is injected into any component (controller, service, filter or directive) that specifies a dependency on the service.

服务工厂函数生成单个对象或函数表示服务给应用程序的其他部分。服务返回的对象或函数将注入到指定服务依赖关系的任何组件(控制器,服务,过滤器或指令)中。

注册服务

Services are registered to modules via the Module API. Typically you use the Module factory API to register a service:

服务经过Module API注册到模块。一般,您使用Module factory API注册服务:

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

Note that you are not registering a service instance, but rather a factory function that will create this instance when called.

请注意,您没有注册服务实例,而是在调用时将建立此实例的工厂函数。

依赖(Dependencies)

Services can have their own dependencies. Just like declaring dependencies in a controller, you declare dependencies by specifying them in the service's factory function signature. 服务能够有它们本身的依赖项。就像在控制器中声明依赖项同样,你能够经过在服务工厂函数签名中指定依赖项来声明依赖项。 For more on dependencies, see the dependency injection docs. 有关依赖项的更多信息,请参阅依赖注入的文档 The example module below has two services, each with various dependencies: 下面的示例模块有两个服务,每一个服务都有各类依赖项:

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);
        });
      }
    };
  }]);
复制代码

In the example, note that: 在示例中,请注意:

  • The batchLog service depends on the built-in interval andlog services.
    • 该batchLog服务取决于内置interval和log服务
  • The routeTemplateMonitor service depends on the built-in $route service and our custom batchLog service.
    • 该routeTemplateMonitor服务取决于内置$route 服务和咱们的自定义batchLog服务。
  • Both services use the array notation to declare their dependencies.
    • 两种服务都使用数组表示法来声明它们的依赖项。
  • The order of identifiers in the array is the same as the order of argument names in the factory function.
    • 数组中标识符的顺序与工厂函数中参数名称的顺序相同。

使用provide注册一个服务(Registering a Service withprovide)

You can also register services via the provide service inside of a module's config function:
你还可使用模块内部的配置函数provide注册服务

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

This technique is often used in unit tests to mock out a service's dependencies. 这个技术经过用于单元测试,以模拟服务的依赖关系

单元测试(Unit Testing)

The following is a unit test for the notify service from the Creating AngularJS Services example above. The unit test example uses a Jasmine spy (mock) instead of a real browser alert.

var mock, notify;
beforeEach(module('myServiceModule'));
beforeEach(function() {
  mock = {alert: jasmine.createSpy()};

  module(function($provide) {
    $provide.value('$window', mock);
  });

  inject(function($injector) {
    notify = $injector.get('notify');
  });
});

it('should not alert first two notifications', function() {
  notify('one');
  notify('two');

  expect(mock.alert).not.toHaveBeenCalled();
});

it('should alert all after third notification', function() {
  notify('one');
  notify('two');
  notify('three');

  expect(mock.alert).toHaveBeenCalledWith("one\ntwo\nthree");
});

it('should clear messages after alert', function() {
  notify('one');
  notify('two');
  notify('third');
  notify('more');
  notify('two');
  notify('third');

  expect(mock.alert.calls.count()).toEqual(2);
  expect(mock.alert.calls.mostRecent().args).toEqual(["more\ntwo\nthird"]);
});
复制代码
相关文章
相关标签/搜索