250.md 8.7 KB
Newer Older
W
wizardforcel 已提交
1 2
{% raw %}

W
wizardforcel 已提交
3 4 5 6
# AngularJS 服务(内置和自定义)

> 原文: [https://howtodoinjava.com/angularjs/angularjs-services-built-in-and-custom/](https://howtodoinjava.com/angularjs/angularjs-services-built-in-and-custom/)

W
wizardforcel 已提交
7
正如我们在 [Angular 介绍](//howtodoinjava.com/angularjs/angularjs-tutorial-helloworld-example/)中了解到的,服务是**无状态对象和单例对象**,它们为 Web 应用提供功能。 例如,`$http`是用于对 Web 服务器进行 HTTP 调用的核心服务。 简单来说,您可以将 Angular 服务假定为可重用代码块,它执行一个或多个相关任务(例如 Java 中带有静态方法的工具类)。 在 AngularJS 中,有几个内置服务 – 您也可以创建自己的自定义服务。
W
wizardforcel 已提交
8 9 10 11 12 13 14 15 16

```java
Table of Contents

Built-in Services
Creating Custom Services
How to use Services
```

W
wizardforcel 已提交
17
## 内置 Angular 服务
W
wizardforcel 已提交
18

W
wizardforcel 已提交
19
如前所述,Angular 提供了几种内置服务,这些服务可以即时使用。 在运行时,这些服务会自动向依赖项注入器注册,因此您可以通过使用依赖项注入轻松地将它们合并到您的 angular 应用中。 例如,要在控制器中使用`$http`服务,请按以下步骤注入服务:
W
wizardforcel 已提交
20 21 22 23 24 25 26

```java
module.controller('DemoController', function( $http ){
    //...
});
```

W
wizardforcel 已提交
27
让我们列出有 Angular 的内置服务。
W
wizardforcel 已提交
28 29

| 服务名称 | 描述 |
W
wizardforcel 已提交
30
| --- | --- |
W
wizardforcel 已提交
31
| `$anchorScroll` | 提供滚动到`$location.hash()`中指定的页面锚点的功能 |
W
wizardforcel 已提交
32
| `$animate` | 该服务公开了一系列 DOM 工具方法,这些方法提供对动画挂钩的支持。 |
W
wizardforcel 已提交
33
| `$animateCss` | 默认情况下,仅当包含`ngAnimate`时,此服务才会执行动画。 |
W
wizardforcel 已提交
34
| `$cacheFactory` | 构造缓存对象,放置和检索键值对并为其提供对其他服务的访问权限的工厂。 |
W
wizardforcel 已提交
35 36
| `$templateCache` | 首次使用模板时,会将其加载到模板缓存中以便快速检索。 |
| `$compile` | 将 HTML 字符串或 DOM 编译到模板中,并生成模板函数,然后可以使用该函数将范围和模板链接在一起。 |
W
wizardforcel 已提交
37
| `$controller` | 这负责实例化 Angular 控制器组件。 |
W
wizardforcel 已提交
38
| `$document` | 指定对`window.document`元素的 [jQuery 包的](//howtodoinjava.com/scripting/jquery/javascript-dom-objects-vs-jquery-objects/)引用。 |
W
wizardforcel 已提交
39
| `$exceptionHandler` | Angular 表达式中任何未捕获的异常都委托给此服务。 默认实现只是委派给`$log.error`,它将其记录到浏览器控制台中。 |
W
wizardforcel 已提交
40
| `$filter` | 过滤器用于格式化显示给用户的数据。 |
W
wizardforcel 已提交
41
| `$httpParamSerializer` | 默认的`$http`参数序列化程序,将对象转换为字符串。 |
W
wizardforcel 已提交
42 43 44 45 46
| `$httpParamSerializerJQLike` | 替代`$http`参数序列化器,它遵循 jQuery 的`param()`方法逻辑。 序列化程序还将按字母顺序对参数进行排序。 |
| `$http` | 此服务有助于通过浏览器的`XMLHttpRequest`对象或`JSONP`与远程 HTTP 服务器进行通信。 |
| `$xhrFactory` | 用于创建`XMLHttpRequest`对象的工厂函数。 |
| `$httpBackend` | 用于处理浏览器不兼容。 |
| `$interpolate` | 将带有标记的字符串编译为插值函数。 HTML `$compile`服务使用此服务进行数据绑定。 |
W
wizardforcel 已提交
47
| `$interval` | Angular 的`window.setInterval`包装器。 |
W
wizardforcel 已提交
48
| `$locale` | 提供各种 Angular 组件的本地化规则。 |
W
wizardforcel 已提交
49
| `$location` | 它解析浏览器地址栏中的 URL,并使该 URL 可用于您的应用。 对地址栏中 URL 的更改将反映到`$location`服务中,对`$location`的更改将反映到浏览器地址栏中。 |
W
wizardforcel 已提交
50 51 52
| `$log` | 控制台日志。 |
| `$parse` | 将 Angular 表达式转换为函数。 |
| `$q` | 帮助您异步运行函数,并在完成处理后使用它们的返回值(或错误)。 |
W
wizardforcel 已提交
53 54
| `$rootElement` | Angular 应用的根元素。 |
| `$rootScope` | 范围提供了模型和视图之间的分离。 这是针对根范围的。 每个应用都有一个根范围。 |
W
wizardforcel 已提交
55 56 57
| `$sceDelegate` | 由后端`$sce`使用。 |
| `$sce` | 为 AngularJS 提供严格的上下文转义服务。 |
| `$templateRequest` | 它运行安全检查,然后使用`$http`下载提供的模板,并在成功后将内容存储在`$templateCache`中。 |
W
wizardforcel 已提交
58
| `$timeout` | Angular 的`window.setTimeout()`包装器 |
W
wizardforcel 已提交
59
| `$window` | 对浏览器的`window`对象的引用。 尽管`window`在 JavaScript 中全局可用,但由于它是全局变量,因此会引起可测试性问题。 在 Angular 上,我们始终通过`$window`服务来引用它,因此可以对其进行覆盖,删除或模拟以进行测试。 |
W
wizardforcel 已提交
60 61 62 63 64

*参考: [https://docs.angularjs.org/api/ng/service](https://docs.angularjs.org/api/ng/service)*

## 创建自定义 Angular 服务

W
wizardforcel 已提交
65
将应用的业务逻辑和通用操作放在一个地方总是一个好的设计。 这样可以提高代码的可重用性,并避免代码重复。 您应将所有此类逻辑放入自定义 Angular 服务中。 这使代码模块化并且更易于维护。
W
wizardforcel 已提交
66

W
wizardforcel 已提交
67
此外,您的代码变得更具可测试性。 请记住,Angular 为单元测试提供了一流的支持。 因此,我们可以为这些服务快速编写测试,并避免许多可能的缺陷。
W
wizardforcel 已提交
68 69 70

声明 angularjs 服务的方式主要有两种。 让我们了解两种方式:

W
wizardforcel 已提交
71
#### 使用`module.service('serviceName', function(){})`
W
wizardforcel 已提交
72

W
wizardforcel 已提交
73
当您使用`module.service()`**创建服务时**,作为第二个参数传递的`function()`的实例成为 AngularJS 注册并随后在需要时注入到其他服务/控制器的服务对象。
W
wizardforcel 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

使用`module.service()`在自定义服务对象中声明方法的语法为:

```java
module.service('DemoService', function() {
	//"this" will be used as service instance
    this.firstMethod = function() {
        //..
    }

    this.someOtherMethod = function() {
        //..
    }
});
```

W
wizardforcel 已提交
90
#### 使用`module.factory('factoryName', function(){})`
W
wizardforcel 已提交
91

W
wizardforcel 已提交
92
当您使用`module.factory()`创建服务时,作为第二个参数传递的`function()`**返回值**将成为 AngularJS 注册并稍后在需要时注入到其他服务/控制器的服务对象。
W
wizardforcel 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206

使用`module.factory()`在自定义服务对象中声明方法的语法为:

```java
module.factory('DemoService', function() {
	//"factory" will be used as service instance
	var factory = {}; 

    factory.firstMethod = function() {
        //..
    }

    factory.someOtherMethod = function() {
        //..
    }

    return factory;
});
```

## 如何使用 AngularJS 服务

此示例演示了自定义服务的用法,该服务具有用于显示不同时区的当前时间的逻辑。 首先创建自定义服务。

```java
var app = angular.module('myApp', []);

//Create a function
function TimeObj() {
    var cities = {
        'Los Angeles': -8,
        'New York': -5,
        'London': 0
    };
    this.getTZDate = function(city) {
        var localDate = new Date();
        var utcTime = localDate.getTime() + localDate.getTimezoneOffset() * 60 * 1000;
        return new Date(utcTime + (60 * 60 * 1000 * cities[city]));
    };
    this.getCities = function() {
        var cList = [];
        for (var key in cities) {
            cList.push(key);
        }
        return cList;
    };
}

//Register as service 'TimeService'
app.service('TimeService', [TimeObj]);

```

现在要使用此服务,请使用如下控制器:

```java
app.controller('LAController', ['$scope', 'TimeService',
    function($scope, timeS) {
        $scope.myTime = timeS.getTZDate("Los Angeles").toLocaleTimeString();
    }
]);

app.controller('NYController', ['$scope', 'TimeService',
    function($scope, timeS) {
        $scope.myTime = timeS.getTZDate("New York").toLocaleTimeString();
    }
]);

app.controller('LondonController', ['$scope', 'TimeService',
    function($scope, timeS) {
        $scope.myTime = timeS.getTZDate("London").toLocaleTimeString();
    }
]);

```

现在,您可以在网页中使用控制器显示不同的时间。

```java
<html ng-app="myApp">
	<head>
		<title>AngularJS Custom Time Service</title>
		<style>
			span {
				color: lightgreen; background-color: black;
				border: 3px ridge; padding: 2px;
				font: 14px/18px arial, serif; 
			}
		</style>
	</head>
	<body>
		<h2>Custom Time Service:</h2><hr>

		<div ng-controller="LAController">
		Los Angeles Time:
		<span>{{myTime}}</span>
		</div><hr>

		<div ng-controller="NYController">
		New York Time:
		<span>{{myTime}}</span>
		</div><hr>

		<div ng-controller="LondonController">
		London Time:
		<span>{{myTime}}</span>
		</div>

	</body>
</html>
```

输出将如下所示:

W
wizardforcel 已提交
207
请参阅 [CodePen](https://codepen.io) 上的 [Angular 服务演示 – 时区示例](https://codepen.io/howtodoinjava/pen/jWxYKB/),作者为 Lokesh([@howtodoinjava](https://codepen.io/howtodoinjava))。
W
wizardforcel 已提交
208

W
wizardforcel 已提交
209
这就是 **AngularJS 服务入门教程**的全部内容。 将我的问题放在评论部分。
W
wizardforcel 已提交
210

W
wizardforcel 已提交
211 212 213
学习愉快!

{% endraw %}