点击查看AngularJS系列目录
转载请注明出处:http://www.cnblogs.com/leosx/


服务

Angular的服务也是使用依赖注入(dependency injection (DI))去获取相关对象的实例的。你可以在整个app当中,去共享你的代码。

Angular的服务有两点特性:

1、懒惰实例化 -- 只有当你依赖了它的时候,它才会被创建。

2、单例模式 -- 每一个依赖了它的组件只会创建一个实例。服务的创建是由服务工厂来创建的。

Angular官方提供了一些常用的服务(例如:$http),但是但部分app中,我们都会需要去创建属于自己的服务。

注意: Angular自己提供的服务或者核心对象,都是以$ 开头的(例如 $http) 也就是说在自定义服务的时候,最好不要以$开头。以免覆盖影响到了Angular自带的服务或功能。

使用服务

要使用Angular的服务,就得将它注入给需要它的组件(包括:指令directive、控制器controller、服务service、过滤器filter等)。具体如何操作,见下面例子:

第一个文件:index.html

<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>

第二个文件: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');
});

示例如下:

自定义服务

开发人员可以通过注册服务的名字实现服务的工厂方法(factory)来自定义服务。

服务会被服务工厂(factory)所创建,并且是对于一个调用组件来说,是单例的。然后再把这个实例注入到依赖这个服务的组件的构造函数中去。

注册服务

服务是使用Module factory(模块的factory方法) API去注册的。如下:

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

服务的依赖

服务也可以有自己的依赖。就像在一个控制器中声明依赖一样,我们同样可以通过在服务的工厂函数参数中指定它们所依赖其它组件。

关于更多和依赖相关的文档,点击这里(dependency injection)可以查看。

下面的例子中的module有着两个服务,每个服务都有着依赖组件的组件。

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) {
$rootScope.$on('$routeChangeSuccess', function() {
batchLog($route.current ? $route.current.template : null);
});
}]);

在上面的例子中:

1、batchLog 服务依赖了Angular内置的$interval 服务和 $log 服务。

2、routeTemplateMonitor 服务依赖了Angular内置的 $route 服务和我们自定义的batchLog 服务。

3、这两种服务都使用数组表示法来声明它们的依赖。

4、注意,依赖声明的顺序就是构造函数中参数的顺序。

使用 $provide注册服务

你也可以使用模块的配置功能$provide去注册服务(自定义服务),如下:

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

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

单元测试

下面是一个用于测试上面的例子创建的notify服务的单元测试。单元测试示例发出的告警是使用Jasmine spy 模拟出来的,而不是真正的浏览器发出的告警信息。

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.callCount).toEqual(2);
expect(mock.alert.mostRecentCall.args).toEqual(["more\ntwo\nthird"]);
});

AngularJS–service(服务)的更多相关文章

  1. 解决VMWARE NAT SERVICE服务无法启动或服务消失的问题

    解决VMWARE NAT SERVICE服务无法启动或服务消失的问题 2016-02-02 11:18 2012人阅读 评论(2) 收藏 举报  分类: 网络通信(3)  今日使用VMware中的Wi ...

  2. 使用axis开发web service服务端

    一.axis环境搭建 1.安装环境 JDK.Tomcat或Resin.eclipse等. 2.到 http://www.apache.org/dyn/closer.cgi/ws/axis/1_4下载A ...

  3. win7提示“User Profile Service服务未能登录”

    注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 最近,有个同事打电话告诉我说他的用户名无法登陆到系统,提示“User Profile Service服务未能登录,无法加载用户配置文 ...

  4. Android 通过JNI实现守护进程,使得Service服务不被杀死

    来自: http://finalshares.com/read-7306 转载请注明出处: http://blog.csdn.net/yyh352091626/article/details/5054 ...

  5. Service服务

    Android多线程: 定义线程的2种方式: 1.继承Thread类,重写run()方法,new一个实例,用start()方法启动:new MyThread().start(); 2.实现Runnab ...

  6. Centos6.5 设置Tomcat8 service服务实现自启动和服务管理

    Centos6.5 设置Tomcat8 service服务实现自启动和服务管理 将tomcat设置成像apache,nginx一样. 用serviec xxxx start/stop/restart ...

  7. Android 综合揭秘 —— 全面剖释 Service 服务

    引言 Service 服务是 Android 系统最常用的四大部件之一,Android 支持 Service 服务的原因主要目的有两个,一是简化后台任务的实现,二是实现在同一台设备当中跨进程的远程信息 ...

  8. win8.1 user profile service 服务登录失败

    在Win 8.1 上新建个用户后,不能登录. 出现 user profile service 服务登录失败. 无法加载用户配置文件. 网上大部分相同提示的问题是有关已有账号不能再次登陆的. 解决方式是 ...

  9. Android中Service(服务)详解

    http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...

随机推荐

  1. C / C++ 运行环境搭建教程

    C / C++ 运行环境搭建教程 一.实验环境 本机操作系统:Windows 7 64位 虚拟机:VMware Workstation 12 pro 虚拟机操作系统:Linux CentOS 7 二. ...

  2. 初学者入门web前端:C#基础知识:函数

    入行前端对函数的掌握程度有可能直接影响以后工作的效率,使用函数可以高效的编写编码,节省时间,所以我整理了C#中最基础的函数知识点,虽然我在学习中 遇到很多问题,但是只要能够解决这些问题,都是好的. 一 ...

  3. grunt之watch续

    上一回没有说完,我就是这样,做之前心中波澜壮阔,锦绣山河,等画完小草开始烦躁,完成鲜花出现动摇,然后心神涣散,最后虎头蛇尾. 现在弥补下之前遗漏的问题. watch(V0.6.1)的tasks和opt ...

  4. C# 索引器简介

    索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,是程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了数组和集合成员时,索引器 ...

  5. 转: 【Java并发编程】之十八:第五篇中volatile意外问题的正确分析解答(含代码)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17382679 在<Java并发编程学习笔记之五:volatile变量修饰符-意料之外 ...

  6. 转: 深入Java虚拟机】之二:Class类文件结构

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17675609 平台无关性 Java是与平台无关的语言,这得益于Java源代码编译后生成的存 ...

  7. KVM网页管理工具WebVirtMgr部署

    KVM-WebVirtMgr 0ther https://github.com/retspen/webvirtmgr/wiki System Optimization(Only CentOS6.X) ...

  8. 201521123048 《Java程序设计》第7周学习总结

    1. 本周学习总结 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 public boolean contains(Object o) { re ...

  9. 201521123024 《Java程序设计》第5周学习总结

    1. 本周学习总结 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出结果. 不能编 ...

  10. 201521123013 《Java程序设计》第1周学习总结

    1. 本章学习总结 1.Java是面向对象的编程语言,它在通过jvm和jre将其转成本地机器代码,达到一次撰写,到处运行的效益,实现跨平台运行,代码开源,使用范围广. 2.了解jdk.jre.jvm的 ...