服务

AngularJS服务是使用依赖注入(DI)连接在一起的可替代对象。 可以使用服务在整个应用程式中整理和分享程式码。

AngularJS服务有:

  • 延迟初始化 - AngularJS只在应用程序组件依赖它时实例化服务。
  • 单例 - 依赖于服务的每个组件获取对服务工厂生成的单个实例的引用。

AngularJS提供了几个有用的服务(如$http),但对于大多数应用程序,你也想创建自己的。像其他核心的AngularJS标识符一样,内置服务总是以$开头(例如$http)。

使用服务

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

index.html

<div id="simple" ng-controller="MyController" ng-app="myServiceModule">
<p>让我们尝试这个简单的通知服务,注入到控制器</p>
<input ng-init="message='test'" ng-model="message" >
<button ng-click="callNotify(message);">NOTIFY</button>
<p>(必须点击3次才能看到提醒)</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 = [];
}
};
}]);

protractor.js

it('should test service', function() {
expect(element(by.id('simple')).element(by.model('message')).getAttribute('value'))
.toEqual('test');
});

需要点击三次NOTIFY按钮才会出现弹出框内容

创建服务

应用程序开发人员可以使用AngularJS模块注册服务的名称和服务工厂函数来自由定义自己的服务。

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

注册服务

服务通过Module API注册到模块。 通常您使用Module factory API注册服务:

var myModule = angular.module('myModule', []);
myModule.factory('serviceId', function() {
var shinyNewServiceInstance;
// 构造shinyNewServiceInstance的工厂函数体
return shinyNewServiceInstance;
});

此时不是注册服务实例,而是一个在调用时将创建此实例的工厂函数。

依赖

服务可以有自己的依赖。 就像在控制器中声明依赖项一样,可以通过在服务的工厂函数签名中指定依赖性来声明它们。

下面的示例模块有两个服务,每个具有各种依赖关系:

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

/**
*`batchLog'服务允许消息在内存中排队,并且每50秒刷新到console.log
*/
batchModule.factory('batchLog', ['$interval', '$log', function($interval, $log) {
var messageQueue = []; function log() {
if (messageQueue.length) {
$log.log('batchLog messages: ', messageQueue);
messageQueue = [];
}
} // 开始定期检查
$interval(log, 50000); return function(message) {
messageQueue.push(message);
}
}]); /**
*`routeTemplateMonitor`监视每个`$ route`更改,并通过`batchLog`服务记录当前模板
*/
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服务和$rootscope和我们的自定义batchLog服务。
  • 两个服务都使用数组符号来声明它们的依赖关系。
  • 数组中标识符的顺序与工厂函数中参数名称的顺序相同。

还可以通过模块的配置函数中的$provide服务注册服务:

angular.module('myModule', []).config(['$provide', function($provide) {
$provide.factory('serviceId', function() {
var shinyNewServiceInstance;
// 构造shinyNewServiceInstance的工厂函数体
return shinyNewServiceInstance;
});
}]);

这种技术通常用于单元测试中来模拟服务的依赖。

单元测试

以下是来自上面的创建服务示例的通知服务的单元测试。 单元测试示例使用Jasmine spy(mock),而不是真正的浏览器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"]);
});

Angular开发者指南(五)服务的更多相关文章

  1. ZooKeeper开发者指南(五)

    引言 这个文档是为了想利用ZooKeeper的协调服务来创建分布式应用的开发者提供的指南.它包括概念和实践的信息. 这个文档的一开始的的四部分呈现了不同ZooKeeper高级概念的的讨论.理解Zook ...

  2. Angular开发者指南(二)概念概述

    template(模板):带有附加标记的模板HTML directives(指令):使用自定义属性和元素扩展HTML model(模型):用户在视图中显示的数据,并与用户进行交互 scope(作用域) ...

  3. Angular开发者指南(一)入门介绍

    什么是Angular AngularJS是动态Web应用程序的结构框架. 它允许您使用HTML作为模板语言,并允许您扩展HTML的语法以清晰,简洁地表达应用程序的组件.AngularJS的数据绑定和依 ...

  4. Angular开发者指南(七)依赖注入

    依赖注入 依赖注入(DI)是一种软件设计模式,处理组件如何获取其依赖关系. AngularJS注入器子系统负责创建组件,解析它们的依赖关系,并根据请求将它们提供给其他组件. 使用依赖注入 DI遍布An ...

  5. Angular开发者指南(六)作用域

    什么是作用域? 作用域是引用应用程序模型的对象. 它是表达式的执行上下文. 作用域以层次结构排列,模仿应用程序的DOM结构,它可以观察表达式和传播事件. 作用域的特征 Scope提供API($watc ...

  6. Angular开发者指南(四)控制器

    了解控制器controller 在AngularJS中,Controller由JavaScript构造函数定义,用于扩充AngularJS Scope. 当控制器通过ng-controller指令连接 ...

  7. Angular开发者指南(三)数据绑定

    数据绑定 AngularJS应用程序中的数据绑定是模型和视图组件之间的数据的自动同步. AngularJS实现数据绑定的方式可以将模型视为应用程序中的单一来源. 视图是模型在任何时候的投影. 当模型更 ...

  8. [译]AngularJS 1.3.0 开发者指南(一) -- 介绍

    [译]AngularJS 1.3.0 开发者指南(一) -- 介绍 Angular是什么 ? AngularJS是一款针对动态web应用的结构框架. 它可以让像使用模板语言使用HTML, 并且可以扩展 ...

  9. [译]AngularJS 1.3.0 开发者指南(一) -- 介绍 (转)

    http://www.cnblogs.com/lzj0616/p/6440563.html [译]AngularJS 1.3.0 开发者指南(一) -- 介绍 Angular是什么 ? Angular ...

随机推荐

  1. Hexo博客NexT主题美化之评论系统

    前言 更多效果展示,请访问我的博客 https://kangmingxian.github.io/ 效果图:   image Valine 诞生于2017年8月7日,是一款基于Leancloud的快速 ...

  2. 系统学习python第三天学习笔记

    day02补充 运算符补充 in value = "我是中国人" # 判断'中国'是否在value所代指的字符串中. "中国"是否是value所代指的字符串的子 ...

  3. Springboot项目绑定域名,使用Nginx配置Https

    一.https 简介     HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HT ...

  4. php 去除中间空格

    <?php $str = 'a b c d e'; echo preg_replace('# #','',$str);//输出 "abcde"

  5. 取石子游戏(gcd)

    蒜头君和花椰妹在玩一个游戏,他们在地上将n颗石子排成一排,编号为1到n.开始时,蒜头君随机取出了2颗石子扔掉,假设蒜头君取出的2颗石子的编号为a, b.游戏规则如下,蒜头君和花椰妹2人轮流取子,每次取 ...

  6. LeetCode——48. 旋转图像

    给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转图像. 示例 1: 给定 m ...

  7. 修改自己的centos输入法

    当自己的centos连上网时,就可以修改自己的输入法了 http://jingyan.baidu.com/album/da1091fb3e7f8a027849d681.html?picindex=2

  8. 吴裕雄--天生自然Linux操作系统:Linux 用户和用户组管理

    Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统. 用户的账号一方面可以帮助系统管理员对使用系统的用户进行 ...

  9. 微服务项目开发学成在线_day03 CMS页面管理开发

    springboot引入mangodb依赖坐标:在spring-boot集成条件下,使用mongodb的DAO层开发. swagger查看接口文档,请求地址:http://localhost:3100 ...

  10. PAT Advanced 1074 Reversing Linked List (25) [链表]

    题目 Given a constant K and a singly linked list L, you are supposed to reverse the links of every K e ...