1.引言
在本篇博客中主要介绍一下如何自定义服务,为什么要自定义服务?首先我们应该意识到:在开发的过程中,controller
这一层应该很薄;也就是说,应用里大部分的业务逻辑 和持久化数据都应该放在 service
里。controller
中就不应该存储持久化数据,出于内存性能的考虑,controller 只在需要 的时候才会初始化,一旦不需要就会被抛弃。因此,每次当你切换或刷新页面的时候, Angular 会清空当前的 controller。与此同时,service 可以用来永久保存应用的数据, 并且这些数据可以在不同的 controller 之间使用。
关于自定义服务有三种方法,三种方法分别为:
provider
factory
service
这三种方法创建自定义服务都有着自己的特点,我们以前说过:服务的类型有两种,一种是具有供应商的服务,一种是不具备供应商的服务,通过Provider
方法创建的服务是具有供应商的,因此我们可以将Provider
创建的服务传入config
方法进行配置;而Factory
,Service
方法创建的服务是不具备供应商概念的,Factory
,Service
两个方法创建服务也有细微的区别,接下来我们分别使用这三种方法创建自定义服务。
2.通过service
方法自定义服务
service
方法定义的服务 是用new
关键字实例化的。因此,我们可以直接给this
添加属性,然后服务返回this
。我们也可以将自定义的服务注入到我们的控制器中。使用service
方法自定义服务也有两种方式,一种是通过模块的service
方法自定义服务,一种是通过$provide
服务自定义服务。接下来我们就来看一下这两种方法。
- 重点说明
service
自定义服务是new
一个函数对象(一定是对象)
2.1 使用模块service
方法自定义服务
- 自定义服务,服务名称为
$myService
var app = angular.module('myApp',[]);
app.service("$myService",function(){
var _name="wpx";
this.getName=function(){
return _name;
}
})
- 在控制区中注入我们的服务
app.controller("firstController", function ($scope,$myService) {
$scope.name=$myService.getName()
})
- html片段
<div ng-controller="firstController">{{name}}</div>
- 运行结果
2.2 使用$provide
服务的service
方法自定义服务
- 自定义我们的服务:
$myService
var app = angular.module('myApp',[], function ($provide) {
$provide.service("$myService", function () {
var _name="wpx";
this.getName= function () {
return _name;
}
})
});
- 将服务注入到控制器中
app.controller("firstController", function ($scope,$myService) {
$scope.name=$myService.getName()
})
- html 片段
<div ng-controller="firstController">{{name}}</div>
- 运行结果
2.3 service
自定义服务解释
- 首先我们注意到:
service
自定义的服务是一个函数。 service
自定义的服务函数是可以注入其他服务的,比如我注入$http
服务,可以这么写
//注入其他服务
app.service("$myService",function($http){
})
service
自定义的服务是new
出来的,也就是说改服务的实现和函数类用法一样,比如:
function myClass() {
}
var a=new myClass();
3.通过factory
方法自定义服务
使用factory
方法自定义服务也是有两种方式,通过模块定义,通过$provide
服务的factory
方法定义服务,factory
创建的服务和service
方法定义的服务是有区别的,factory
方法直接把一个函数当成一个对象的$get
方法,因此factory
创建的服务 是可以直接返回字符串的。(service
自定义的服务就不可以直接返回字符串),接下来我们就使用factory
方法自定义我们的服务
- 重点说明
factory
自定义服务是是调用函数 ,然后返回一个对象,或者是数据
3.1 使用模块factory
方法自定义服务
- 自定义服务,服务名称为:
$myFactory1
(返回字符串)
var app = angular.module('myApp',[]);
app.factory("$myFactory1",function(){
return "aaaa";
})
- 自定义服务,服务名称为:
$myFactory2
(返回对象)
app.factory("$myFactory2",function(){
var _name;
function getName(){
return _name;
}
function setName(name)
{
_name=name;
}
return {
getName:getName,
setName:setName
}
})
- 将自定义服务注入到控制器
app.controller("firstController", function ($scope,$myFactory1,$myFactory2) {
$scope.name=$myFactory1
$myFactory2.setName("wpx");
})
app.controller("secondController", function ($scope,$myFactory2) {
$scope.name=$myFactory2.getName()
})
- html片段
<div ng-controller="firstController">{{name}}</div>
<div ng-controller="secondController">{{name}}</div>
- 运行结果
3.2 使用服务factory
方法自定义服务
话不多少,直接上代码
var app = angular.module('myApp',[], function ($provide) {
$provide.factory("factoryName",function () {
//服务代码
})
});
3.3 解释factory
方法自定义的服务
- 第一点:
factory
的服务是当作方法来调用 - 第二点:
factory
自定义服务也可以注入其他服务,比如:$http
app.factory("$myFactory1",function($http){
//代码实现
//记得return
})
- 第三点:服务是单例的,通过实例我们知道,服务可以在多个控制器之间传递数据(在控制器一中给服务添加数据,然后在控制器2中读取数据)
4.通过provider
方法自定义服务
在前面我们说过provider
方法定义的服务最大的区别在于具有供应商的概念,具有了供应商我们就可以通过config
方法配置一些全局的属性。首先我们先使用provider
定义一个简单的服务。
4.1 provider
定义简单服务
- 使用模块的
provider
定义一个服务(叫做mySelf
)
var app = angular.module('myApp',[]);
app.provider("$mySelf", function () {
this.$get=function(){
return {
message:"$mySelf"
}
}
})
- 使用
$provide
定义一个服务(叫做mySelf
)
var app = angular.module('myApp',[], function ($provide) {
$provide.provider("$mySelf", function () {
this.$get=function(){
return {
message:"$mySelf"
}
}
})
});
- 将自定义服务注入到控制器
app.controller("firstController", function ($scope,$mySelf) {
$scope.message=$mySelf.message
})
- html片段
<div ng-controller="firstController">{{message}}</div>
- 运行结果
4.2 provider
定义需要配置的服务
刚刚我们说过:通过provider
定义的服务会生成供应商,有供应商的服务可以通过模块的config
方法进行配置,接下来我们来使用一下供应商。
- 创建一个自定义的服务(该服务需要配置一个
attr
属性)
var app = angular.module('myApp',[]);
app.provider("$mySelf", function () {
//需要配置的属性
this.attr="";
this.$get=function(){
var that=this;
var service={};
var _attr="$mySelf.attr";
service.getAttr=function(){
return _attr+"-----"+that.attr;
}
return service;
}
})
- 通过供应商配置属性(在服务的后面添加
Provider
就是供应商)
app.config(function ($mySelfProvider) {
$mySelfProvider.attr="config.attr";
})
- 将服务注入到控制器中
app.controller("firstController", function ($scope,$mySelf) {
$scope.attr=$mySelf.getAttr();
})
- html片段
<div ng-controller="firstController">{{attr}}</div>
- 运行结果
4.3 provider
创建的服务需要注意的地方
- 使用
provider
方法创建服务具有供应商 - 我们可以通过
config
配置供应商的属性 - 使用
provider
自定义服务是如何创建的?首先我们看一下服务的定义
//首先我们new了一下,服务函数然后使用this.$get方法,将得到的结果注入到了控制器中,也就是说provider方法创建的服务其实是service方法和factory方法的一个组合使用。
app.provider("$mySelf", function () {
//需要配置的属性
this.attr="";
this.$get=function(){
var that=this;
var service={};
var _attr="$mySelf.attr";
service.getAttr=function(){
return _attr+"-----"+that.attr;
}
return service;
}
})
- *
5 使用供应商修改默认表达式符号
前面我们说了,部分服务是具有供应商的,既然AngularJS
提供了一些默认的服务,那么就应该有一些默认的供应商,这里我们就使用一下默认的供应商修改一下默认的表达式,默认表达式是{{表达式}}
,现在我们将其修改为#表达式#
。
5.1 使用$interpolateProvider
供应商修改默认表达式服务
- 使用
config
方法设置供应商
var app = angular.module('myApp',[]);
app.config(function ($interpolateProvider) {
$interpolateProvider.startSymbol("#");
$interpolateProvider.endSymbol("#");
})
- 使用新的表达数输出数据
//控制器
app.controller("firstController", function ($scope) {
$scope.attr="hello world";
})
//html片段
<div ng-controller="firstController">#attr#</div>
- 运行结果
6 服务注入,代码压缩问题
在使用服务的时候,不可避免的就会涉及到依赖注入的问题,如果服务的名称过长,那么我们多次使用服务代码的体积就会变得越来越大,所以我们在注入服务的时候可以给服务:起别名。利用非常短的别名来代替服务,接下来我们看一看如何注入我们的服务,以$scope
服务为例:
app.controller("firstController",["$scope","$rootScope",function ($s,$rs) {
$s.name="wpx";
$rs.age="20";
}])
- html代码片段
<div ng-controller="firstController">{{name}}---{{age}}</div>
- 运行结果
- 在上面的例子中,我们使用
$s
代替$scope
,$rs
代替$rootScope
,那么在控制器中,我们就可以直接使用别名,这样就会减少代码量 - 只要是涉及服务注入的情况都可以使用这种方法进行代码压缩。