服务

服务是什么

控制器的生命是有限的,在需要时才被实例化,一旦不需要就被销毁以节省内存提升性能。每次切换或者重新加载视图的时候当前控制器就会被 AngularJS 销毁。

如果需要在应用的整个生命周期中保持数据就需要使用服务,使用它在控制器之间通信,并保持数据的一致性。

服务是一个单例对象,在每一个应用中只会被初始化一次(被$injector实例化)。

我们可以将网络请求以及数据持久化的功能写在 Service 模块中

注册服务

通过$injector创建和注册服务的方式有多种。通常使用angular.modulefactory api 来创建服务。

DEMO:

HTML 代码如下,这个页面实现了一个输入用户名来获取该用户 github 账号下信息的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!--服务 ServiceScript.js-->
<div ng-controller="ServiceTestController">
<label for="username">
Type a github username
</label>
<input type="text"
id="username"
ng-model="username"
placeholder="Enter a github username">
<ul>
<li ng-repeat="event in events">
{{event | json}}
{{event.actor.login}} {{event.repo.name}}
</li>
</ul>
</div>

<div ng-controller="ServiceTestControllerDelay">
<label>
Type a github username
</label>
<input type="text"
ng-model="username"
placeholder="Enter a github username">
<ul>
<ul>
<li ng-repeat="event in events">
{{event | json}}
{{event.actor.login}} {{event.repo.name}}
</li>
</ul>
</div>

Service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var service = angular.module("myApp.service",[]);
service.factory('firstService', function ($http) {//注入$http依赖

var githubUrl = 'https:/api.github.com';

var runUserRequest = function (username, path) {
//从使用JSONP调用Github API的$http服务中返回promise对象
return $http({
method: 'JSONP',
url: githubUrl + '/users/' +
username + '/' +
path + '?callback=JSON_CALLBACK'
});
};


var serviceInstance = {
events: function (username) {
return runUserRequest(username, 'events');
}
};
return serviceInstance;//singleton obj
});

Controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
app.controller('ServiceTestController',
function ($scope, firstService) {
$scope.$watch('username', function (newUsername) {
firstService.events(newUsername).success(
function (data, status, headers) {
$scope.events = data.data;
console.log(data.data);
});
});
});//不推荐在控制其中使用 $watch

app.controller('ServiceTestControllerDelay',
function ($scope, firstService, $timeout) {
var timeout;
$scope.$watch('username', function (newUsername) {
if (newUsername) {
if (timeout)//350ms 内又会进来,然后任务就被全部取消
$timeout.cancel(timeout);
timeout = $timeout(function () {//句柄
firstService.events(newUsername).success(
function (data, status, headers) {
$scope.events = data.data;
console.log(data.data);
});
}, 350);
}
});
});//不推荐在控制其中使用 $watch

创建服务其他的方式

  1. service() 可以为服务提供构造函数。

  2. provider() 如果希望在 config() 函数中可以对服务进行配置必须使用provider()来定义服务。

  3. constant() 可以将一个现有的常量值注册成为服务。

  4. value() 将一个值注册成为一个服务。

    注意:constant() 和 value() 方法的区别在于,常量可以注入到配置函数(config())中,但值不行。通常使用 value() 注册服务对象或函数,用constant()来配置数据。

  5. decorator() 装饰器十分强大,可以对服务进行拦截,中断甚至替换功能等操作。