AngularJS–service(服务)
点击查看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(服务)的更多相关文章
- 解决VMWARE NAT SERVICE服务无法启动或服务消失的问题
解决VMWARE NAT SERVICE服务无法启动或服务消失的问题 2016-02-02 11:18 2012人阅读 评论(2) 收藏 举报 分类: 网络通信(3) 今日使用VMware中的Wi ...
- 使用axis开发web service服务端
一.axis环境搭建 1.安装环境 JDK.Tomcat或Resin.eclipse等. 2.到 http://www.apache.org/dyn/closer.cgi/ws/axis/1_4下载A ...
- win7提示“User Profile Service服务未能登录”
注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 最近,有个同事打电话告诉我说他的用户名无法登陆到系统,提示“User Profile Service服务未能登录,无法加载用户配置文 ...
- Android 通过JNI实现守护进程,使得Service服务不被杀死
来自: http://finalshares.com/read-7306 转载请注明出处: http://blog.csdn.net/yyh352091626/article/details/5054 ...
- Service服务
Android多线程: 定义线程的2种方式: 1.继承Thread类,重写run()方法,new一个实例,用start()方法启动:new MyThread().start(); 2.实现Runnab ...
- Centos6.5 设置Tomcat8 service服务实现自启动和服务管理
Centos6.5 设置Tomcat8 service服务实现自启动和服务管理 将tomcat设置成像apache,nginx一样. 用serviec xxxx start/stop/restart ...
- Android 综合揭秘 —— 全面剖释 Service 服务
引言 Service 服务是 Android 系统最常用的四大部件之一,Android 支持 Service 服务的原因主要目的有两个,一是简化后台任务的实现,二是实现在同一台设备当中跨进程的远程信息 ...
- win8.1 user profile service 服务登录失败
在Win 8.1 上新建个用户后,不能登录. 出现 user profile service 服务登录失败. 无法加载用户配置文件. 网上大部分相同提示的问题是有关已有账号不能再次登陆的. 解决方式是 ...
- Android中Service(服务)详解
http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...
随机推荐
- Andrew Ng机器学习课程笔记--week9(上)(异常检测&推荐系统)
本周内容较多,故分为上下两篇文章. 一.内容概要 1. Anomaly Detection Density Estimation Problem Motivation Gaussian Distrib ...
- JEasyPoi 2.1.4 (Jeecg订制) 版本发布,Excel 和 Word 简易工具类
JEasyPoi 2.1.4 (jeecg订制)版本发布,EasyPoi Excel 和 Word 简易工具类 easypoi 功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 ...
- SoapUI 之 JDBC请求
之前有试过Jmeter的JDBC请求,挺方便的,今天下午闲来没事,看见soapUI里面也有一个JDBC请求,便也来试试. 首先添加一个JDBC请求,然后直接把Jmeter的一些链接参数复制过去,一直报 ...
- 聊一聊Redis的数据结构
如果没有记错的话,应该是在两个月前把 我们经常看到此类的文章: Redis的五种数据结构 Redis的数据结构以及对应的使用场景 其实以数据结构这个词去说明Redis的String.Hash.List ...
- throws Exception方法异常处理机制
public class T4 { private String sex; public String getSex() { return sex; } public void setSex(Stri ...
- JMockit使用总结
Jmockit可以做什么 使用JMockit API来mock被依赖的代码,从而进行隔离测试. 类级别整体mock和部分方法重写 实例级别整体mock和部分mock mock静态方法.私有变量.局部方 ...
- Docker 集群环境实现的新方式
近几年来,Docker 作为一个开源的应用容器引擎,深受广大开发者的欢迎.随着 Docker 生态圈的不断建设,应用领域越来越广.云计算,大数据,移动技术的快速发展,加之企业业务需求的不断变化,紧随技 ...
- MySQL的JOIN(二):JOIN原理
表连接算法 Nested Loop Join(NLJ)算法: 首先介绍一种基础算法:NLJ,嵌套循环算法.循环外层是驱动表,循坏内层是被驱动表.驱动表会驱动被驱动表进行连接操作.首先驱动表找到第一条记 ...
- jQuery控制a标签不可点击 不跳转
jquery禁用a标签方法1 01 02 03 04 05 06 07 08 09 10 11 12 $(document).ready(function () { $("a ...
- box-sizing怪异盒子模型在移动端应用
盒子模型不必多少,公认的盒子模型 总宽度=width + padding(padding-left,padding-right) + border(border-left,border-right) ...