angularJS module里的'服务'
首先,为了举栗子,先写好如下的模型,控制器,html:
html:

<!DOCTYPE html>
<html ng-app="serviceApp">
<head>
<title>服务</title>
<meta charset="utf-8">
<script src="../angular.js"></script>
<script src="script.js"></script>
<!-- <script src="script_2.js"></script>-->
</head>
<body >
<div ng-controller="myCtrl">
name:{{name}}
<br/>
age:{{age}}
<br/>
love:{{love}}
<br/>
money:{{money}}
<br/>
id:{{id}}
</div>
<hr/>
<div ng-controller="myOtherCtrl">
name:{{name}}
<br/>
love:{{love}}
<br/>
</div>
<hr/>
</body>
</html>

js:

var serviceApp = angular.module('serviceApp',[]);
serviceApp.controller('myCtrl',function($scope,myConfig){
$scope.name = myConfig.name;
$scope.love = myConfig.love;
$scope.age = myConfig.age;
$scope.money = myConfig.money;
$scope.id = myConfig.getId();
$scope.$watch(myConfig.love,function(){$scope.love = myConfig.love;});
})
serviceApp.controller('myOtherCtrl',function($scope,myConfig){
$scope.name = myConfig.name;
$scope.love = myConfig.love;
angular.extend(myConfig,{love:'zxg'});
$scope.$watch(myConfig.love,function(){$scope.love = myConfig.love;});
});

如上,serviceApp模型里有两个控制器,myCtrl和myOtherCtrl,这两个控制器都注入了myConfig这个服务.我们在后面就通过创建不同的myConfig服务来查看结果
一.constant服务:
app.constant('name',obj)
name为服务的名字,obj为一个json对象.
js:

serviceApp.constant('myConfig',{
name:'code_bunny',
age:12,
getId:function(){
return 1
}
});

运行结果: http://jsfiddle.net/f9qq0t50/1/
说明:
constant创建服务返回一个json对象(也就是第二个参数中传入的对象),这个对象里可以有参数,可以有方法,并且,属性和方法都可以在控制器中修改,新增,但是按照它的设计本意,一般constant创建的服务不会去修改它的内容,需要修改内容,最好用value来创建服务.
注意点:
1.它是一个引用对象,无论被注入多少个控制器中,实际都指向同一个对象,所以,无论修改其中的哪一个,其它所有的服务都会被改变.
2.服务修改过后,ng不会自动同步,简单的说,就是它没有做到自动双向绑定数据,比如在这里给服务新增了love属性:angular.extend(myConfig,{love:'zxg'}),我需要使用$scope.$watch(myConfig.love,function(){$scope.love = myConfig.love;})这样才能把love属性值同步到视图中.
3.constant服务不能通过decorator进行装饰,(什么是装饰下面会讲到)
二.value服务:
app.value('name',obj)
name为服务的名字,obj为一个json对象.
js:

serviceApp.value('myConfig',{
name:'code_bunny',
age:12,
getId:function(){
return 1
}
});

serviceApp.config(function($provide){
$provide.decorator('myConfig',function($delegate){
$delegate.money = '100w';
return $delegate
})
});
运行结果: http://jsfiddle.net/p0dqr7wy/1/
说明:
value创建服务返回一个json对象(也就是第二个参数中传入的对象),这个对象里可以有参数,可以有方法,并且,属性和方法都可以在控制器中修改,新增,按照它的设计本意,如果属性和方法需要被修改内容,就用value来创建服务.
constant和value主要就是用于存放一些数据或方法以供使用,区别是constant一般是存放固定内容,value存放可能会被修改的内容
注意点:
1.同constant注意点1
2.同constant注意点2
3.value可以被装饰,所以这里myConfig服务拥有了money属性.(装饰具体怎么用,下面会说)
三.factory服务
app.factory('name',function(){return obj})
name为服务的名字,第二个参数传入一个函数,函数需要有一个返回值obj,返回一个对象.实际被注入的服务就是这个对象.
js:

serviceApp.factory('myConfig',function(){
var myname = 'code_bunny';
var age = 12;
var id = 1;
return {
name: myname,
age: age,
getId: function(){
return id
}
}
});

或者是这样:

serviceApp.factory('myConfig',function(){
return new constructorFun()
});
function constructorFun(){
var myname = 'code_bunny';
var age = 12;
var id = 1;
this.name = myname;
this.age = age;
this.getId = function(){
return id
}
}

装饰部分代码:

serviceApp.config(function($provide){
$provide.decorator('myConfig',function($delegate){
console.log($delegate);
$delegate.money = '100w';
return $delegate
})
});

运行结果:
说明:
factory服务是最常见最常用的服务类型,几乎可以满足90%的自己开发的需求,使用它可以编写一些逻辑,通过这些逻辑最后返回所需要的对象.比如使用$http来获取一些数据.我们就在factory创建的服务里抓取数据,最后返回.
它和constant,value最大的区别是,factory服务是有一个处理过程,经过这个过程,才返回结果的.
注意点:
1.同constant注意点1
2.同constant注意点2
3.factory返回的服务也可以被装饰,所以这里myConfig服务拥有了money属性.(装饰具体怎么用,下面会说)
四.service服务
app.service('name',constructor)
name为服务的名字,constructor是一个构造函数.
js:

serviceApp.service('myConfig',function(){
var myname = 'code_bunny';
var age = 12;
var id = 1;
this.name = myname;
this.age = age;
this.getId = function(){
return id
}
});

或者是这样:

serviceApp.service('myConfig',constructorFun);
function constructorFun(){
var myname = 'code_bunny';
var age = 12;
var id = 1;
this.name = myname;
this.age = age;
this.getId = function(){
return id
}
}

装饰部分代码同上.
运行结果:
说明:
service和factory的区别在于,它第二个参数传入的是一个构造函数,最后被注入的服务是这个构造函数实例化以后的结果.所以基本上使用service创建的服务的,也都可以使用factory来创建.
所以这里,factory服务的第二种写法和使用service是一致的:
serviceApp.factory('myConfig',function(){
return new constructorFun()
});
//等价于
serviceApp.service('myConfig',constructorFun);
注意点:
1.同constant注意点1
2.同constant注意点2
3.service返回的服务也可以被装饰,所以这里myConfig服务拥有了money属性.(装饰具体怎么用,下面会说)
五.provider服务

app.provider('name',function(){
....
return {
...
$get:function(){
...
return obj
}
}
})

name为服务的名字,第二个参数接受一个函数,函数返回一个对象,返回的对象比如要有$get方法,$get方法必须要返回一个对象obj,这个对象就是真正被注入的服务.
栗子一:
js:

serviceApp.provider('myConfig',function(){
return {
$get:function(){
var myname = 'code_bunny';
var age = 12;
var id = 1;
return {
name: myname,
age: age,
getId: function(){
return id
}
}
}
}
});

装饰部分代码同上.
运行结果: http://jsfiddle.net/2pz2ft73/
说明:
provider服务的第二个参数的返回值中必须要有$get方法(除了$get,还可以有其它方法,后面的例子会说到),$get方法就相当于factory服务的第二个参数,最后要返回一个对象,这个对象就是真正被注入的服务:
栗子二:
js:

serviceApp.provider('myConfig',function(){
var id = 1;
return {
setID:function(newID){
id = newID
},
$get:function(){
var myname = 'code_bunny';
var age = 12;
return {
name: myname,
age: age,
getId: function(){
return id
}
}
}
}
});
serviceApp.config(function(myConfigProvider){
myConfigProvider.setID(2)
});

装饰部分代码同上.
运行结果:http://jsfiddle.net/hcpemex3/
说明:
这里的provider服务不仅仅返回了$get方法,还返回了setID方法,然后id变量是写在函数里的,返回值的外面,形成一个闭包,可以被修改.
然后,在provider服务里定义的方法,可以在config函数里调用.注意调用的格式:
serviceApp.config(function(myConfigProvider){
myConfigProvider.setID(2)
});
被注入的服务名不叫myConfig,而是myConfigProvider.然后在函数里面可以调用myConfigProvider的setID方法(也就是myConfig的setID方法).
通过这种方式,使得我们的服务可以被手动配置,比如这里可以配置id.
ng有很多内置的服务都有这样的功能,比如$route服务,$location服务,当我们通过$routeProvider和$locationProvider来配置的时候,其本质就是这些服务是通过provider创建的.
注意点:
1.同constant注意点1
2.同constant注意点2
3.provider返回的服务也可以被装饰,所以这里myConfig服务拥有了money属性.(装饰具体怎么用,下面会说);
六.装饰服务
其实通过上面这么多的例子,看也能看懂装饰是什么了...
app.config(function($provide){
$provide.decorator('name',function($delegate){
$delegate.money = '100w';
return $delegate
})
});
同样是通过config,在参数函数中注入$provider服务,$provider服务有个decorator方法,它接受两个参数,第一个参数'name',是要被装饰的服务的名字,第二个参数是一个函数,函数中注入$delegate,$delegate就是被装饰的服务的实例,然后在函数中操作$delegate,就相当于操作了该服务的实例.
注意:
1.最后一定要return $delegate,这样服务才算被装饰完成了.
2.constant服务是不能被装饰的.
栗子就不说了吧,上面的都是~
总结上面的内容:
1.服务的实例被注入到控制器以后,都是一个引用对象,无论被注入多少个控制器中,实际都指向同一个对象,所以,无论修改其中的哪一个,其它所有的服务都会被改变.
2.服务的实例被修改过后,ng不会自动同步,需要使用$scope.$watch()监测其变化并手动刷新视图.
3.constant服务不能通过decorator进行装饰.
4.一些固定的参数和方法,使用constant
5.可能被修改的参数和方法,使用value
6.通过逻辑处理后得到的参数或方法,使用factory
7.可以使用factory的也可以使用service,反之亦然(一般就是用factory)
8.可以手动配置参数的服务,使用provider
七.可以创建不同实例的服务
之前我们说到,所有的服务的实例都是引用对象,无论被注入多少个控制器中,实际都指向同一个对象,所以,无论修改其中的哪一个,其它所有的服务都会被改变.这就是ng服务的设计模式,一般不需要去改变,但如果有特殊需要,要能够每次注入控制器后得到新的实例,可以这样做:
我们给服务添加了一个方法,每次执行一次这个方法,都会创建一个新的实例,这样,虽然在控制器里注入的是服务实例还是同一个,但是在调用创建实例方法的时候,都会创建一个新的实例,然后就可以单独修改这个实例,而不会影响到其它控制器:如下
js:

var serviceApp = angular.module('serviceApp',[]);
serviceApp.controller('myCtrl',function($scope,myConfig){
var myConfigConstant = myConfig.create();
$scope.name = myConfigConstant.name;
$scope.age = myConfigConstant.age;
angular.extend(myConfigConstant,{love:'zxg'});
$scope.love = myConfigConstant.love;
$scope.id = myConfigConstant.getId();
$scope.$watch(myConfigConstant.name,function(){$scope.name = myConfigConstant.name;});
myConfigConstant.name = 'white_bunny';
});
serviceApp.controller('myOtherCtrl',function($scope,myConfig){
var myConfigConstant = myConfig.create();
$scope.love = myConfigConstant.love;
$scope.name = myConfigConstant.name;
$scope.$watch(myConfigConstant.name,function(){$scope.name = myConfigConstant.name;});
});
/************************创建实例的服务************************/
serviceApp.factory('myConfig',function(){
return {
//服务返回的对象有一个create方法,该方法每次被执行都会返回一个新的constructorFun实例
create: constructorFun.createNew
}
});
//创建一个构造函数
function constructorFun(){
var myname = 'code_bunny';
var age = 12;
var id = 1;
this.name = myname;
this.age = age;
this.id = id
}
//给构造函数添加createNew方法,用于实例化一个constructorFun.
constructorFun.createNew = function(){
return new constructorFun()
};
//给构造函数添加原型的方法.使得它的实例可以继承.
constructorFun.prototype = {
getId: function(){
return this.id
}
};

运行效果: http://jsfiddle.net/fpoq4deo/1/
好了~五种服务类型就全部讲完啦~~~
全部代码托管: https://github.com/OOP-Code-Bunny/angular/tree/master/service
angularJS module里的'服务'的更多相关文章
- angular学习笔记(十五)-module里的'服务'
本篇介绍angular中的模块:module 在笔记(二)http://www.cnblogs.com/liulangmao/p/3711047.html里已经讲到过模块,这篇主要讲模块的 '服务' ...
- 【AngularJS中的自定义服务service VS factory VS provider】---它们的区别,你知道么?
在介绍AngularJS自定义服务之前,我们先来了解一下AngularJS~ 学过HTML的人都知道,HTML是一门很好的伪静态文本展示设计的声明式语言,但是,要构建WEB应用的话它就显得乏力了. 而 ...
- 千万不要在module里扩展较多逻辑,很容易引起项目异常。
NOP项目 为保持紧跟NOP更新,项目组坚持不改NOP源码. 以触发器,插件化开发为拓展模式 NOP自定义好的接口或完全独立的新拓展功能很容易插件化. 但部分功能要在NOP原项目上扩展修改在不改源码的 ...
- AngularJS——第8章 服务
第8章 服务 服务是一个对象或函数,对外提供特定的功能. 8.1 内建服务 1. $location是对原生Javascript中location对象属性和方法的封装. // $location内置服 ...
- k8s~k8s里的服务Service
k8s用命名空间namespace把资源进行隔离,默认情况下,相同的命名空间里的服务可以相互通讯,反之进行隔离. 服务Service 1.1 Service Kubernetes中一个应用服务会有一个 ...
- AngularJS 不得不了解的服务 $compile 用于动态显示html内容
项目中一度纠结与AngularJS如何动态显示不同的html内容. 本来是希望直接使用下面的语句来实现: <div> </div> 但是很尴尬的是,这样不能识别出html标签, ...
- AngularJS中实现日志服务
本篇体验使用AngularJS自定义一个记录日志的服务. 在AngularJS中,服务的一些写法是这样的: var app = angular.module('app',[]); app.provid ...
- angularJS中如何写服务
服务的用途 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性 服务提供了把特定功能相关联的方法集中在一起的接口 如何创建服务 angularJS ...
- AngularJS -- Module (模块)
点击查看AngularJS系列目录 转载请注明出处:http://www.cnblogs.com/leosx/ 什么是AngularJS的模块 我们所说的模块,是你的AngularJS应用程序的一个组 ...
随机推荐
- 免费SVN、Git项目托管主机推荐
Unfuddle 200MB的免费空间,界面友好,特性丰富,支持Git,但只能一个账户一个用户并且只允许一个项目,付费服务相对来说价格偏高 CodeSpaces 500MB,一个账户两个免费用户,付费 ...
- Win10 快捷键
Win + D # 最小化桌面 Win + L # 锁屏 Win + E # 打开"我的电脑" Win + I # 打开设置 Win + P # 启动投屏 Win + G # 屏幕 ...
- 使用 requests 进行身份认证
如下图,有些网站需要使用用户名密码才可以登录,我们可以使用 requests 的 auth 参数来实现 import requests req = requests.get("http:// ...
- PPT高手必须树立的十个理念
08 2014年08月 [263职场技巧]PPT高手必须树立的十个理念 理念一:文字是用来瞟的,不是读的 我们时不时听到这样的言论:“PPT很简单,就是把Word里的文字复制.粘贴呗.”这其实是对PP ...
- VS中快捷键修改以及快捷键的查看
eclipse用习惯了一直想把VS中的alt+/改为自动补全,同时自定义一下C#环境下自动加入命名控件的快捷键,前段时间摸索了一下,找到了比较好的方法 首先是vs中修改快捷键的方法:工具->选项 ...
- PHP域名解析(一个IP绑多域名)----看看可以,并不值得借鉴
PHP域名解析(一个IP绑多域名)----看看可以,并不值得借鉴 好处当然是不用买多网卡.不用设置其它端口为WEB端口了,一张网卡上.都用同一个80端口建很多网站. 假设有三个域名: [url ...
- open-falcon之transfer
功能 负责数据转发,接受agent上报的数据,然后使用一致性hash规则对数据进行分片,最后将分片后的数据分别转发至judge,graph 对接收到的数据进行合法性校验.规整 针对每个后端实例维护一个 ...
- .net环境下的缓存技术-转载!
摘要: 介绍缓存的基本概念和常用的缓存技术,给出了各种技术的实现机制的简单介绍和适用范围说明,以及设计缓存方案应该考虑的问题(共17页) 1 概念 1.1 缓存能解决的问题 · 性 ...
- 【存储过程】用SQL语句获得一个存储过程返回的表
定义一个存储过程如下: create proc [dbo].[test1] @id int as select 1 as id,'abc' as name union all select @id a ...
- 为什么WAN口IP和外网IP不一样(不一致)?
正常的网络应该是动态公网ip,也就是路由器里面的WAN口IP与www.ip138.com上面显示的是一致的,不一致的话则说明该网络被电信或者联通做了NAT转发,导致您获取到了一个虚假的IP地址,无法用 ...