AngularJS 中 Provider 的用法及区别
在一个分层良好的 Angular 应用中,Controller 这一层应该很薄。也就是说,应用里大部分的业务逻辑和持久化数据都应该放在 Service 里。
为此,理解 AngularJS 中的几个 Provider 之间的区别很有必要。
Provider 创建的新服务都可以用来注入。包括:
- provider
- factory
- service
- constant
- value
另外,内建的服务 $controller 和 $filter 也可以被注入,同时也可以使用这些服务来获得新的过滤器和控制器。
下面介绍一下各自的用法和 provider、factory、value 三者之间的区别。
provider
用于产生一个可配置的 Service,由两部分组成。第一部分的变量和函数是可以在 app.config 函数中访问的,可以在它们被其他地方访问到之前来修改它们。定义方式如下:
1 |
app.provider('myProvider', function(){
|
在 app.config 函数对 a 进行修改:
1 |
app.config(function(myProviderProvider){
|
这也是在有如此简单的 factory 的情况下还使用 provider 的原因。
第二部分的变量和函数是通过 $get() 函数返回的,可以在任何传入了该 provider 的控制器中进行访问的。
1 |
app.provider('myProvider', function(){
|
factory
factory 返回一个对象。只需要创建一个对象,为它添加属性,然后返回这个对象。在控制器中注入该 factory,即可使用它的所有属性。
1 |
app.factory('myFactory', function(){
|
看得出来,factory 的第二个参数就是 provider 中 $get 要对应的函数实现。
service
service 类似于一个构造器, 通过 new 关键字实例化对象,将一些属性和方法直接添加到 this上,在创建 service 对象时,this 会被作为返回值返回。
1 |
app.service('myService', function(){
|
注入 myService 的控制器可以访问到绑定在 myService 中 this 上的 setA() , getA() 和foo() 三个方法。
constant
constant 用于定义常量,一旦定义就不能被改变。可以被注入到任何地方,但是不能被装饰器(decorator)装饰。
1 |
app.constant('APP_KEY', 'a1s2d3f4')
|
value
与 constant 一样,可以用来定义值。但与 constant 的区别是:可以被修改,可以被 decorator 装饰,不能被注入到 config 中。
1 |
app.value('version', '1.0')
|
value 通常用来为应用设置初始值。
decorator
比较特殊,它不是 provider 。它是用来装饰其他 provider 的,不过 constant 除外,因为从源码可以看出,constant 不是通过 provider() 方法创建的。
下面是一个用 decorator 装饰 value 的栗子。
1 |
app.value('version', '1.0');
|
那如果要使用前面的 myService service,但是其中缺少一个你想要的 greet 函数。可以修改 service 吗?答案是不行!但是可以装饰它:
1 |
app.decorator('myService', function($delegate){
|
$delegate 代表实际上的 service 实例。
装饰一个 service 的能力是非常实用的,尤其是当我们想要使用第三方的 service 时,此时不需要将代码复制到我们的项目中,而只需要进行一些修改即可。
源码
下面是 provider、factory、service、value、constant 和 decorator 的底层实现:
1 |
function provider(name, provider_) {
|
可以看出,除了 constant,另外几个最终调用的都是 provider(decorator比较特殊,不算)。
总结
什么时候使用 provider 而不用 factory ?
provider 是 factory 的加强版。当需要一个可配置的 factory 的时候,使用 provider。
简单介绍一下 AngularJS 运行应用的过程,分两个阶段,config 阶段和 run 阶段。config 阶段是设置任何的 provider 的阶段。也是设置任何的指令,控制器,过滤器以及其它东西的阶段。在 run 阶段,AngularJS 会编译你的 DOM 并启动应用。
factory 和 service 的区别是什么?
factory 是普通 function,而 service 是一个构造器(constructor),这样 Angular 在调用 service 时会用 new 关键字,而调用 factory 时只是调用普通的 function,所以 factory 可以返回任何东西,而 service 可以不返回。
参考
- AngularJS 之 Factory vs Service vs Provider
- [AngularJS系列(4)] 那伤不起的provider们啊~ (Provider, Value, Constant, Service, Factory, Decorator)
- 理解AngularJS中的Service类型
- AngularJS中的Provider们:Service和Factory等的区别
AngularJS 中 Provider 的用法及区别的更多相关文章
- angularjs中provider,factory,service的区别和用法
angularjs中provider,factory,service的区别和用法 都能提供service,但是又有差别 service 第一次被注入时实例化,只实例化一次,整个应用的生命周期中是个单例 ...
- AngularJS中forEach的用法
AngularJS中当我们需要遍历某个数组的时候,我们会用到forEach语法.AngularJS中forEach的用法如下: angular.forEach(array,function(obj,i ...
- AngularJS中$interval的用法
在AngularJS中$interval用来处理间歇性处理一些事情. 最常用的是: var app = angular.module("app",[]); app.controll ...
- AngularJS 服务 provider factory service及区别
一.概念说明 1.服务是对公共代码的抽象,如多个控制器都出现了相似代码,把他们抽取出来,封装成一个服务,遵循DRY原则,增强可维护性,剥离了和具体表现相关的部分,聚焦于业务逻辑或交互逻辑,更加容易被测 ...
- angularjs中ng-switch的用法
<!DOCTYPE html> <html lang="zh-CN" ng-app="app" ng-controller="ctr ...
- angularjs中$parse的用法
转载自:https://umur.blog/2014/02/25/advanced-angular-parse/ 高级Angular:$ parse 如果你想加强你的AngularJS知识,$ par ...
- AngularJS中ng-options简单用法及预选项失败的原因
刚刚接触AngularJs,记录一下ng-options的使用. 1.构造key-value数据 $scope.types = [ {id:"1",type:"AA&qu ...
- angularjs 中的$digest和$apply区别
$digest和$apply 在Angular中,有$apply和$digest两个函数,我们刚才是通过$digest来让这个数据应用到界面上.但这个时候,也可以不用$digest,而是使用$appl ...
- Mybatis的mapper文件中$和#的用法及区别详解
https://www.2cto.com/database/201806/752139.html用了一段时间的Mybatis了,对于$和#的用法老是很迷糊,特此记下加深记忆. 简单来说 #{} 会在将 ...
随机推荐
- java通过jacob来读取word转换为htm格式
转自:http://blog.csdn.net/chinapi_hzh/article/details/5798689 因为微软没有公开word源代码,所以直接用java流来读取word的后果是读出来 ...
- 关于LightMapping和NavMesh烘焙的动态载入
熟悉unity的朋友都应该知道,unity有内部LightMapping烘焙和NavMesh寻路的功能.但这些非常好用的功能,都是基于对某个已经保存的关卡(scene)进行烘焙(Bake)的操作,我一 ...
- VS2010 VC++ 项目添加引用 出现 Internal CPS Error问题原因及解决办法
在VS2010 VC++ 项目添加引用时,有时会出现Internal CPS Error错误,提示信息: 'Internal CPS Error: We couldn't find the exist ...
- stl map中的lower_bound和 upper_bound
map中的lower_bound和upper_bound的意思其实很简单,就两句话: map::lower_bound(key):返回map中第一个大于或等于key的迭代器指针 map::upper_ ...
- 10723 Cyborg Genes (LCS + 记忆化搜索)
Problem F Cyborg Genes Time Limit 1 Second September 11, 2132. This is the day that marks the beginn ...
- 如何修改Git commit的信息
原文地址: http://xiguada.org/change-git-commit-message Git cimmit信息push后,如何修改,amend可以修改最后一次commit信息,但对 ...
- Windows 批处理 ping 某个网段
原文: https://blog.csdn.net/leuxcn/article/details/51288248 ------------------------------------------ ...
- Android程序怎么做单元测试
如何进行Android单元测试 Menifest.xml中加入: <application>中加入: <uses-library android:name="android ...
- k-means聚类学习
4.1.摘要 在前面的文章中,介绍了三种常见的分类算法.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应.但是很多时候上述条件得不到满足,尤其是在 ...
- LDA基本介绍以及LDA源码分析(BLEI)
基本介绍: topic model,主题模型介绍:http://www.cnblogs.com/lixiaolun/p/4455764.html 以及 (http://blog.csdn.net/h ...