1.概述
● 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器(controller)之间进行通信,并且能保证数据的一致性。
● 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化),并且是延迟加载的(需要时才会被创建)。服务提供了把与特定功能相关联的方法集中在一起的接口。
● 创建服务:只需注册这个服务即可。
服务被注册后,angularjs编译器就可以引用它,并且在运行时把它当做依赖加载到controller中即可。
● 步骤:
◆ 注册服务
◆ 在controller中调用服务
angular.module("myApp",[]);
.factory("fruit",function(){
return {
"name1":"apple",
"name2":"orange"
}
})
.controller("myCtrl1",function($scope,fruit){ //fruit:服务名,注意:形参中自定义的放在后面,内置的放在前面
$scope.fruitName = fruit.name1 + fruit.name2;
});
2.创建服务的方法
2.1 factory(name,getFn)
● name:注册的服务名
● getFn:这个函数会在angularjs创建服务实例时被调用。
◆ 因为服务是单例对象,getFn在应用的生命周期内只会被调用一次。
◆ 在定义服务时,getFn可以接受一个包含可被注入对象的数组或函数。
既可以是一个函数也可以是一个数组
通过将方法设置为服务对象的一个属性来将其暴露给外部。
◆ getFn函数可以返回简单类型、函数乃至对象等任意类型的数据(单例服务对象)。
必须有return返回
● factory
可以返回任何东西,它实际上是一个只有$get
方法的provider
//用方括号声明
angular.module('myApp.services',[])
.factory('githubService',[function($http){
return ...
}]);
//用函数声明
angular.module('myApp.services',[])
.factory('githubService',function($http){
return ...
});
githubService需要访问$http服务,我们将$http服务当做angularjs应用的一个依赖注入到工厂函数中。
2.2 service(name,constructor)
注册一个支持构造函数的服务
● name:注册的服务名
● constructor:构造函数,我们调用它来实例化服务对象。
◆ service()会在创建实例时通过new关键字来实例化服务对象。
2.3 constant(name,value)
● name:注册的服务名
● value:(常量,不可更改)需要注册的常量的值(值或对象)
constant()返回一个注册后的服务实例
2.4 value(name,value)
● name:注册的服务名
● value:(值,可以改变)
如果服务的$get方法返回的是一个常量,可以通过value()方便的注册服务。
2.5 provider(name,aProvider)
● provider
是以上几个服务的老大,上面的几乎(除了
constant
)都是
provider
的封装
● provider
必须返回一个定义有
$get()
函数的对象
,当然也可以说
provider
是一个可配置的
factory
● 如果希望在config()中对服务进行配置,必须用provider()来定义服务。(例3)
2.6 value()和constant()区别
● 值是否可变
constant()定义的常量值不可以改变
value()定义的值可以改变
● 是否可以注入到配置函数(config)
constant()定义的常量值可以注入到配置函数(config)中
value()定义的值不行
● 是否可以被装饰器装饰
constant()不能被装饰器(decorator
)装饰
value()可以被decorator
装饰
app.config(function ($provide) {
$provide.constant('movieTitle', 'The Matrix');
});
3.服务在config()中
3.1 constant()
app.config(function ($provide) {
$provide.constant('movieTitle', 'The Matrix');
});
app.constant('movieTitle', 'The Matrix');
3.2 value()
app.config(function ($provide) {
$provide.value('movieTitle', 'The Matrix')
});
app.value('movieTitle', 'The Matrix');
3.3 service()
app.config(function ($provide) {
$provide.service('movie', function () {
this.title = 'The Matrix';
});
});
app.service('movie', function () {
this.title = 'The Matrix';
});
3.4 factory()
app.config(function ($provide) {
$provide.factory('movie', function () {
return {
title: 'The Matrix';
}
});
});
app.factory('movie', function () {
return {
title: 'The Matrix';
}
});
3.5 provider()
app.provider('movie', function () {
var version;
return {
setVersion: function (value) {
version = value;
},
$get: function () {
return {
title: 'The Matrix' + ' ' + version
}
}
}
});
app.config(function (movieProvider) { //命名:movie+Provider //作用域:app.provider的外层return
movieProvider.setVersion('Reloaded');
});
app.controller('ctrl', function (movie) { //注入的是app.provider的$get
expect(movie.title).toEqual('The Matrix Reloaded');
});
4. 服务在多个controller之间通信
保持数据统一性(数据共享)
5.代码案例
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body ng-app="myApp">
<div ng-controller="myCtrl1">
<p>value:{{uname}}</p>
<p>constant:{{uid}}</p>
<p>factory:{{uperson.age}}</p>
<p>service:{{uaddr}}</p>
</div>
<script src="angularjs.js"></script>
<script>
angular.module("myApp",[])
.value("name","abc") //值是可变的
.value("name","ABC")
.constant("id","12345") //常量是不可变的
.constant("id","54321")
.<span style="background-color: rgb(255, 255, 0);">factory</span>("person",function(){ <span style="background-color: rgb(255, 255, 0);">//必须有返回值return</span>
// return {
// age:10,
// setAge:function(){
// this.age = 20;
// }
// }
return new Person; <span style="background-color: rgb(255, 255, 0);">//factory和service类似,可看作是service的复杂版</span>
})
.<span style="background-color: rgb(255, 255, 0);">service</span>("Addr",function(){ <span style="background-color: rgb(255, 255, 0);">//是构造函数</span>
this.provice = "河北";
this.city = "唐山";
this.getAddr = function(){
return this.provice+this.city;
}
})
.controller("myCtrl1",function($scope,name,id,person,Addr){
$scope.uname = name;
$scope.uid = id;
$scope.uperson = person;
person.setAge();
$scope.uaddr = Addr.getAddr();
});
function Person(){
this.age = 10;
this.setAge = function(){
this.age = 20;
}
}
</script>
</body>
</html>
参考:https://segmentfault.com/a/1190000003096933