林炳文Evankaka原创作品。

转载请注明出处http://blog.csdn.net/evankaka

       本教程使用AngularJs版本号:1.5.3

       AngularJs GitHub: https://github.com/angular/angular.js/

       AngularJs下载地址:https://angularjs.org/

用有过Spring的人都知道。Spring的核心思想就是DI(依赖注入,Dependency Injection)和IOC(控制反转 Invension of Controller),AngularJS的service事实上就是用到了这里的DI思想。那么什么叫做DI?

所谓DI,就是指对象是被动接受依赖类而不是自动去找,换句话说就是指对象不是从容器中查找它依赖的类。而是在容器实例化对象的时候主动将它依赖的类注入给它。我个人的理解就是。你在实例化一个类时,它会自动去实例化它里面所用到的其他实例。所以这就叫依赖注入。在Angular里面,services作为单例对象在须要到的时候被创建,仅仅有在应用生命周期结束的时候(关闭浏览器)才会被清除。而controllers在不须要的时候就会被销毁了。

AngualrJs中可用来注入的有三种类型,service、factory、provider,这三种写法不样。使用方法也都不一样。当中。service仅仅实例化一次。事实上就是单例模式的思想。不管我们在什么地方注入我们的service,将永远使用同一个实例。所以对非常多在controller层中的操作就能够放到serivce层中去。

AngularJS提供例如很多内在的服务。如:$http, $route, $window, $location等。每一个服务负责例如一个特定的任务,$http是用来创建AJAX调用,以获得server的数据。

$route用来定义路由信息等。内置的服务总是前缀$符号。

当中。三者的关系能够看成是下图:

一、Service使用具体解释

(1)定义

一个学用的service使用方法例如以下:

一般直接用this来操作数据、定义函数。

app.service('myService', function() {
var privateValue = "I am Private";
this.variable = "This is public";
this.getPrivate = function() { return privateValue;
};
});

(2)AngularJS中使用DI加入Service的三种方法 
方式1(内联注解。推荐使用):

app.controller('myController', ['$scope', 'dateFilter', function ($scope, dateFilter) { }]);

方式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更可靠(因为Javascript能够被压缩,AngularJS又是通过解析服务名称找到相应Service的。因此Javascript压缩之后AngularJS将无法找到指定的Service,但字符串不会被压缩,因此单独以字符串指定Service的名称能够避免这个问题)
使用方式1或方式2的注意点:
因为上述第二点原因,AngularJS在编译Html时,由$injector将数组中Service的名称与方法体中的Service进行一一映射。这样的映射关系必须遵守由AngularJS的约定:
数组中Service名称的个数必须与方法体中Service名称的个数一致
数组中Service的顺序必须与方法体中Serivce的顺序一致

(3)什么时候适合使用service()方法
service()方法非常适合使用在功能控制比較多的service里面
注意:须要使用.config()来配置service的时候不能使用service()方法

(4)service使用实例

一个完整实例:

<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>AngularJS学习</title>
<script type="text/javascript" src="./1.5.3/angular.min.js"></script>
</head>
<body>
<div ng-controller="myCtrl">
<button ng-click="getPrivate()">按钮一</button>
<button ng-click="getPUbluc()">按钮二</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.getPUbluc = 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,可是终于仅仅实例化了一次!

注意:seivce定义的服务不能在.config中使用。仅仅有provider定义的才干够

二、Factory使用具体解释

Factory 一般就是创建一个对象,然后在对这个对象加入方法与数据,最后将些对象返回就可以。然后注入到Controller层中就可以。
使用实例:
<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>AngularJS学习</title>
<script type="text/javascript" src="./1.5.3/angular.min.js"></script>
</head>
<body>
<div ng-controller="myCtrl">
<button ng-click="getPrivate()">按钮一</button>
<button ng-click="getPUbluc()">按钮二</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.getPUbluc = function() {
alert(myFactory.variable);
};
});
app.controller('myCtrl2', function($scope, myFactory) { });
app.factory('myFactory', function() {
console.log('instance myFactory');
var factory = {};
var privateValue = "I am Private";
factory.variable = "This is public";
factory.getPrivate = function() {
return privateValue;
};
return factory;
});
</script>
</html>

效果:

从以下能够看到仅仅实例化了一次,两下Controller注入同一个factory,可是终于仅仅实例化了一次!
记得一定要return一个Object对象,否则会报例如以下错误:
AngularJS中的Services:

三、provider使用具体解释

    $provide服务负责告诉Angular怎样创造一个新的可注入的东西:即服务。服务会被叫做供应商的东西来定义,你能够使用$provide来创建一个供应商。

你须要使用$provide中的provider()方法来定义一个供应商。同一时候你也能够通过要求$provide被注入到一个应用的config函数中来获得$provide服务。使用方法是返回一个$get函数。注意在config阶段,仅仅有provider能被注入。

其他使用方法和service一样。

以下是一个实例。
<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>AngularJS学习</title>
<script type="text/javascript" src="./1.5.3/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>

效果:

从以下能够看到仅仅实例化了一次:

再来做一个provider实例化的时间測试:

<!DOCTYPE html>
<html lang="zh" ng-app="myApp"> <head>
<meta charset="UTF-8">
<title>AngularJS学习</title>
<script type="text/javascript" src="./1.5.3/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.provider('test', function() {
console.log('instance test');
var f = function(name) {
alert("Hello, " + name);
};
this.$get = function() { //一定要有! return f;
};
});
/*app.config(function(testProvider) {
testProvider('I am config');
});*/ app.config(function($provide) {
$provide.provider('greeting', function() {
this.$get = function() {
return function(name) {
alert("Hello," + name);
};
};
});
/* greetingProvider('ff');*/
});
</script> </html>
页面刷新后,我们发现即使不注入这个providrer。但也它也进行实例化了,而service/factory则是第一次注入时才会初始化。而也这是为什么它能够注入到config的一个原因吧!
什么时候使用provider()方法

(1)当我们希望在应用開始前对service进行配置的时候就须要使用到provider()。例如。我们须要配置services在不同的部署环境里面(开发,演示。生产)使用不同的后端处(2)理的时候就能够使用到了
当我们打算公布开源provider()也是首选创建service的方法。这样就能够使用配置的方式来配置services而不是将配置数据硬编码写到代码里面。

四、Service、Factory、Provider三者差别


1) 用 Factory 就是创建一个对象。为它加入属性,然后把这个对象返回出来。

你把 service 传进 controller 之后,在 controller 里这个对象里的属性就能够通过 factory 使用了。

2) Service 是用"new"keyword实例化的。因此,你应该给"this"加入属性,然后 service 返回"this"。

你把 service 传进 controller 之后,在controller里 "this" 上的属性就能够通过 service 来使用了。

3) Providers 是唯一一种你能够传进 .config() 函数的 service。当你想要在 service 对象启用之前,先进行模块范围的配置,那就应该用 provider。

4)Factory/service是第一个注入时才实例化,而provider不是,它是在config之前就已实例 化好
同一函数三种不同写法:
<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>AngularJS学习</title>
<script type="text/javascript" src="./1.5.3/angular.min.js"></script>
</head>
<body>
<div ng-controller="myCtrl">
<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('myCtrl', 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>
看console的输出,能够知道都仅仅实例 化了一次:

參考文章:
http://www.cnblogs.com/wushangjue/p/4533953.html?utm_source=tuicool&utm_medium=referral
http://www.oschina.net/translate/angularjs-factory-vs-service-vs-provider
http://my.oschina.net/tanweijie/blog/295067
http://www.360doc.com/content/15/1010/18/28162318_504719466.shtml

跟我学AngularJs:Service、Factory、Provider依赖注入使用与差别的更多相关文章

  1. angularjs---服务(service / factory / provider)

    初angularJs时  常写一些不够优雅的代码  !我总结了一下看看各位有没有中枪的!-----( 这里只针对服务service及其相关! ) 以下做法不太优雅 兄弟controller 之间的相同 ...

  2. AngularJS API之$injector ---- 依赖注入

    在AngularJS中也有依赖注入的概念,像spring中的依赖注入,但是又有所不同.Spring中使用构造注入或者设值注入的方式,还需要做一些额外的操作,但是angular中只需要在需要的地方声明一 ...

  3. AngularJs:Service、Factory、Provider依赖注入使用与区别

           本教程使用AngularJS版本:1.5.3        AngularJs GitHub: https://github.com/angular/angular.js/       ...

  4. angular 服务 service factory provider constant value

    angular服务 服务是对公共代码的抽象,由于依赖注入的要求,服务都是单例的,这样我们才能到处注入它们,而不用去管理它们的生命周期. angular的服务有以下几种类型: 常量(Constant): ...

  5. AngularJS学习笔记之依赖注入

    最近在看AngularJS权威指南,由于各种各样的原因(主要是因为我没有money,好讨厌的有木有......),于是我选择了网上下载电子版的(因为它不要钱,哈哈...),字体也蛮清晰的,总体效果还不 ...

  6. AngularJS——第7章 依赖注入

    第7章 依赖注入 AngularJS采用模块化的方式组织代码,将一些通用逻辑封装成一个对象或函数,实现最大程度的复用,这导致了使用者和被使用者之间存在依赖关系. 所谓依赖注入是指在运行时自动查找依赖关 ...

  7. angularJs的作用域和依赖注入

    一.angularJs的作用域 &scope这是局部作用域,先在局部作用域中找,如果没有就在全局作用域中找  &rootScope这是全局作用域 <!DOCTYPE HTML&g ...

  8. angularjs(显示和隐身) 依赖注入

    1.angularjs 隐身参数注入control: 1.control名称 , 2.function,在function内部直接传递参数和方法. var myapp=angular.model(&q ...

  9. AngularJS中的Provider们:Service和Factory等的区别

    引言 看了很多文章可能还是不太说得出AngularJS中的几个创建供应商(provider)的方法(factory(),service(),provider())到底有啥区别,啥时候该用啥,之前一直傻 ...

随机推荐

  1. elasticsearch java 客户端之Client简介

    elasticsearch通过构造一个client对外提供了一套丰富的java调用接口.总体来说client分为两类cluster信息方面的client及数据(index)方面的client.这两个大 ...

  2. Multiple CPUs,Multiple Cores、Hyper-Threading

    CPU Basics: Multiple CPUs, Cores, and Hyper-Threading Explained 现在多数的家用电脑,仍然使用的是 Single CPU,Multiple ...

  3. 1.22 Python基础知识 - 正则表达式

    Python正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re ...

  4. var和ES6的let

    来源自:http://www.jstips.co/zh_cn/javascript/keyword-var-vs-let/ 特此做个笔记 概述 通过 var 定义的变量,它的作用域是在 functio ...

  5. Android Studio使用Mob来获取手机验证码的源码

    本文来自:CSDN 感谢作者:qq_35812301(其实就是我的号!) 查看原文:http://blog.csdn.net/qq_35812301/article/details/79150775 ...

  6. C#如何调用非托管的C++Dll

    现在在Windows下的应用程序开发,VS.Net占据了绝大多数的份额.因此很多以前搞VC++开发的人都转向用更强大的VS.Net.在这种情况下,有很多开发人员就面临了如何在C#中使用C++开发好的类 ...

  7. 【习题 7-6 UVA - 12113】Overlapping Squares

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先预处理出来一个正方形. 然后每次枚举新加的正方形左上角的坐标就可以. 注意覆盖的规则,控制一下就可以. 然后暴力判断是否相同. 暴 ...

  8. 【习题 7-2 UVA-225】Golygons

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 暴力枚举每次走哪里就好. 用一个二维数组来判重.(数据里,要求不能经过一个点两次->但路径可以相交 然后再用一个flag数组, ...

  9. Android应用开发-广播和服务

    广播 广播的概念 现实:电台通过发送广播发布消息,买个收音机,就能收听 Android:系统在产生某个事件时发送广播,应用程序使用广播接收者接收这个广播,就知道系统产生了什么事件. Android系统 ...

  10. ospp.vbs是什么文件?激活过程cscript ospp.vbs命令详解

    ospp.vbs是什么文件?激活过程cscript ospp.vbs命令详解 在Office 2013激活过程中我们经常会用到cscript ospp.vbs这个命令.那么,很有必要来了解一下,osp ...