本篇转载于:http://blog.csdn.net/evankaka
AngularJs GitHub: https://github.com/angular/angular.js/
AngularJs下载地址:https://angularjs.org/
注:代码都亲测过,效果是一样的,所以用了作者原本的图,望谅解
AngularJs中可用来注入的有三种类型,service、factory、provide,这三种写法不一样,用法也不一样,其中,service只实例化一次,其实就是单例模式的思想,无论我们在什么地方注入service,将永远使用同一个实例,所以对很多Controller的操作就可以放到service层中去。
AngularJS提供例如许多的内在服务,如:$http
,$route
、$window
,$location
等等。每个服务负责例如一个特定的任务,$http
是用来创建AJAX调用,已获得服务器的数据。$route
用来定义路由信息等。内置的服务总是前缀$符号。
关系图如下所示:
一、Service使用详解
(1)定义
一般使用this
来操作数据、定义函数。
app.service('myService', function () {
var privateValue='I am priivate';
this.variable = 'This is public';
this.getPrivate = function(){
return privateValue;
};
});
(2)AngularJS中使用DI添加Service的三种方式
方式1(内联注解,推荐使用)
app.controller('myController',['$scope','deteFiler',function($scope,deteFilter){}]);
方式2($inject注解)
var MyController = function($scope,dateFilter){}
MyController.$inject =['$scope','dateFilter'];
someModule.controller('MyController',MyController);
方式3 (隐式注解、不推荐使用);
app.controller('mycontroller',function($scope,dateFilter){});
推荐使用方法1的理由是:
写法上比方法2更简单明了,比方法3更可靠(由于JavaScriptkeyi可以被压缩,AngularJs又是通过解析服务器名称找到对应的Service的,因为JavaScript压缩之后AngularJs将无法找到指定的Service,但字符串不会被压缩,因此单独以字符串指定的Service的名称可以避免这个问题)
使用方法1或方法2的注意点:
由于上述第二点原因:AngularJS在编译Htm时,由$injector将数组中的service的名称与方法中的Service进行--映射。这种映射关系必须遵循由AngularJS的约定:
数组中Service名称的个数必须与方法体中Service名称个数一致
数组中Service的顺序必须与方法体中Service的顺序一致。
(3)什么时候适合使用Service()方法
Service()方法很适合使用在功能控制比较多的Service()里面
*需要使用.config()来配置service的时候不能使用service()方法
(4)service使用实例
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>AngularJs学习</title>
<script type="text/javascript" src="js/angular.min.js"></script>
</head>
<body>
<div ng-controller="MyCtrl">
<button ng-click="getPrivate()">按钮一</button>
<button ng-click="getPublic()">按钮二</button>
</div>
<div ng-controller="MyCtrl2"></div>
</body>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('MyCtrl',function ($scope,myService) {
$scope.getPrivate = function(){
alert(myService.getPrivate());
};
$scope.getPublic = function(){
alert(myService.variable);
};
});
app.controller('MyCtrl2',function ($scope,myService) {
});
app.service('myService', function () {
console.log('instance myService');
var privateValue = 'I am private';
this.variable = 'This is public';
this.getPrivate=function(){
return privateValue;
}
});
</script>
</html>
效果如下:
另外,从控制台可以看出两个Controller注入了同一个Service,但最终只实例化了一次。
image.png
service定义的服务不能在.config中使用!只有providerdingyi定义的才可以。
二、Factory使用详解
Factory一般就是创建一个对象。然后在这个对象添加方法与数据,最后将些对象返回即可,然后注入到Controller层中即可。
使用实例:
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>AngularJs学习</title>
<script type="text/javascript" src="js/angular.min.js"></script>
</head>
<body>
<div ng-controller="MyCtrl">
<button ng-click="getPrivate()">按钮一</button>
<button ng-click="getPublic()">按钮二</button>
</div>
<div ng-controller="MyCtrl2"></div>
</body>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('MyCtrl',function ($scope,myFactory) {
$scope.getPrivate = function(){
alert(myFactory.getPrivate());
};
$scope.getPublic = function(){
alert(myFactory.variable);
};
});
app.controller('MyCtrl2',function ($scope,myFactory) {
});
app.factory('myFactory', function () {
console.log('instance myFactory');
var privateValue = 'I am private';
this.variable = 'This is public';
this.getPrivate=function(){
return privateValue;
};
return factory;
});
</script>
</html>
效果如下:
image.gif
另外,从这里可以看到controller注入同一个factory,但是最终只实例化了一次。
image.png
记住一定要return 一个Object对象,否则会报出一下错误。
image.png
三、provider使用详解
$provide服务负责告诉AngularJs如何r创造一个新的可注入的东西,即服务。服务会被叫做供应商的东西来定义,你可以使用$provide来创建一个供应商。你需要使用$provide中的provider()方法来定义一个供应商,同时也可以通过要求$provide被注入到一个引用的config函数中来获得$provide服务,使用方法是返回一个$get函数,注意的是,在config阶段,只有provider能被注入,其他用法和service一样。
实例:
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>AngularJs学习</title>
<script type="text/javascript" src="js/angular.min.js"></script>
</head>
<body>
<div ng-controller="myCtrl1">
<button ng-click="onclick1()">请点击我1</button>
</div>
<div ng-controller="myCtrl2">
<button ng-click="onclick2()">请点击我2</button>
</div>
</body>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myCtrl1', function ($scope , testProvider) {
$scope.onclick1=function(){
testProvider("林炳文Evankaka");
};
});
app.controller('myCtrl2',function ($scope , testProvider) {
$scope.onclick2 = function(){
testProvider("我到底是谁");
};
});
app.provider('testProvider', function () {
console.log('instance testProvider');
var f = function(name){
alert("hello,"+name);
}
this.$get = function() {
return f;
};
});
</script>
</html>
效果如下:
image.gif
控制台输出内容:
image.png
下面是一个provider实例化的时间测试
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>AngularJs学习</title>
<script type="text/javascript" src="js/angular.min.js"></script>
</head>
<body>
<div ng-controller="myCtrl1">
<button ng-click="onclick1()">请点击我1</button>
</div>
<div ng-controller="myCtrl2">
<button ng-click="onclick2">请点击我2</button>
</div>
</body>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myCtrl1',function ($scope) {
// $scope.onclick1 = function(){
// test("林炳文Evankaka");
// };
});
app.controller('myCtrl2', function ($scope) {
// $scope.onclick2 = function(){
// test("我到底是谁");
// };
});
// app.config(function (testProvider) {
// testProvider('I am config');
// });
app.provider('test', function () {
console.log('instance test')
var f = function(name){
alert("hello,"+name);
}
this.$get = function() {
return f;
};
});
app.config(function ($provide) {
$provide.provider('greetting', function(){
this.$get = function(){
return function(name){
alert('hello,'+name);
}
}
});
// greetingProvider('ff');
});
</script>
</html>
image.png
页面刷新后,即使不注入provider,但它也进行了实例化,而Service/Factory则是第一次注入时才会初始化。而这也是为什么它可以注入到config的一个原因吧。
什么时候使用provider() 方法
(1)当我们希望在应用开始前对Service进行配置的时候就需要使用到provider().。比如,我们需要配置Service在不同的部署环境(开发,演示,生产)使用不同的后端处(2)理的时候,就可以使用到了,当我们打算发布开源provider()也是首选创建service的方法,这样就可以使用配置的方法来配置Services而不是将配置数据硬编码写到代码里。
四、Service、Factory、Provider三者的区别
(1)用Factory
就是创建一个对象,为它添加属性,然后把这个对象返回出来。把Service
传进Controller
之后,在Controller
里这个对象的属性就可以通过factory
使用了。
(2)Service
是用new
关键字实例化的。因此,应该给this
添加属性。然后service
返回this
,把service传进Controller之后,在Controller里this上的属性就可以通过Service来使用了。
(3)providers是唯一一种可以传入.config()
函数的Service。当想要在Service对象启用之前,先进性模块范围的配置,那就应该使用provider
。
(4)Factory/service
是第一个注入时才实例化。而provider不是,它是在config
之前就实例化好了。
同一种函数的三种不同写法:
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>AngularJs学习</title>
<script type="text/javascript" src="js/angular.min.js"></script>
</head>
<body>
<div ng-controller="myCtrl1">
<p>{{ output1 }}</p>
<p>{{ output2 }}</p>
<p>{{ output3 }}</p>
</div>
<div ng-controller="myCtrl2"></div>
</body>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myCtrl1', function ($scope,testService,testFactory,testProvider) {
$scope.output1 = testService.lable;
$scope.output2 = testFactory.lable();
$scope.output3 = testProvider;
});
app.controller('myCtrl2', function ($scope,testService,testFactory,testProvider) {
});
app.service('testService', function () {
console.log('instance testService');
this.lable = 'this is service';
});
app.factory('testFactory', function () {
console.log('instance testFactory');
return {
lable:function(){
return 'this is factory';
}
};
});
app.provider('testProvider', function () {
console.log('instance testProvider');
this.$get = function() {
return 'this is provider';
};
});
</script>
</html>
image.png
看console的输出,可以知道都只实例 化了一次:
image
网友评论