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"]);
});
複製代碼
相關文章
相關標籤/搜索