点击查看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. 入侵拿下DVBBS php官网详细过程(图)

    几 个月前,DVBBS php2.0暴了一个可以直接读出管理员密码的sql注入漏洞,当时这个漏洞出来的时候,我看的心痒,怎么还会有这么弱智的漏洞,DVBBS php2.0这套代码我还没仔细看过,于是5 ...

  2. 【渗透课程】前言-揭开Web渗透与安全的面纱(必看)

    服务器是怎么被入侵的 攻击者想要对一台计算机渗透必须具备以下条件: 1.服务器与客户端能够正常通讯 (服务器是为客户端提供服务的) 2.服务器向客户端提供的权限(服务)或者说是端口. 服务端所提供的服 ...

  3. Java 逆变与协变

    最近一直忙于学习模电.数电,搞得头晕脑胀,难得今天晚上挤出一些时间来分析一下Java中的逆变.协变.Java早于C#引入逆变.协变,两者在与C#稍有不同,Java中的逆变.协变引入早于C#,故在形式没 ...

  4. JavaPOI处理Excel

     java处理excel,心得分享如下,如有不妥或者需要补充的地方,敬请指出,欢迎随时交流 1.加载excel,获得workbook对象 fileTemp = new File(pathOfMExce ...

  5. JDBCTemplate

    1.Spring提供的一个操作数据库的技术JdbcTemplate,是对Jdbc的封装.语法风格非常接近DBUtils. JdbcTemplate可以直接操作数据库,加快效率,而且学这个JdbcTem ...

  6. appium 判断app是否安装

    #coding:utf-8 #Import the common package import os import unittest from appium import webdriver from ...

  7. zabbix上监控docker

    说明 第一种方案,借助docker的python版的api,然后通过自己封装自定义脚本来做,稍微麻烦点,但是可以达到个人自定义的效果. 第二种借助国外的一位大神已经封装好的模板来做,简单省事情,不过功 ...

  8. jre1.8使用ikvm.net8将jar转换为dll以供c#调用

    由于合作方使用.net编程,jar包不能用,需要转换成dll格式,来回转换了十几个dll文件,终于生成了一个可用的.在这里将走过的弯弯绕绕总结下,希望遇到相似问题的同好们,能走得顺利些. 版本问题: ...

  9. matlab-常用函数(2)

    isempty(A) 功能解释 isempty()用来判断 一个矩阵是否为空矩阵,其用法相当于C语言中的"a==NULL". 当参数为空矩阵时,该函数返回逻辑值"1&qu ...

  10. 遇到的一些Jquery函数

     jQuery.extend()        jQuery.merge():函数用于合并两个数组内容到第一个数组. <script> $(function () { ,,], [,,] ...