![](https://i-blog.csdnimg.cn/blog_migrate/e41916b5baa4d08ffca2142f30511070.png)
首先,provider
, value
, constant
, service
, factory
他们都是provider!(decorator
小朋友先搬个小板凳坐在边上等会儿,现在还没轮到你出场哈~)
provider是干啥的?
provider可以为应用提供通用的服务,形式可以是常量,也可以是对象。
比如我们在controller里常用的$http
就是AngularJS框架提供的provider~
- myApp.controller(‘MainController', function($scope, $http) {
- $http.get(…)
- }
在上面的代码里,就可以直接使用$http
包好的各种功能了~
provider
那我们自己想定制一个provider,怎么写呢~
- //定义:
- $provide.provider('age', {
- start: 10,
- $get: function() {
- return this.start + 2;
- }
- });
- //或
- $provide.provider('age', function($filterProvider){
- this.start = 10;
- this.$get = function() {
- return this.start + 2;
- };
- });
- //调用:
- app.controller('MainCtrl', function($scope, age) {
- $scope.age = age; //12
- });
provider的基本原则就是通过实现$get
方法来在应用中注入单例,使用的时候拿到的age
就是$get
执行后的结果。 上面例子中的两种定义方法都可以~
factory
大哥provider
每次出场太繁琐了,如果我就想定义个$get
,没别的乱七八糟的呢?这时候该二哥factory
出场了~
- $provide.provider('myDate', {
- $get: function() {
- return new Date();
- }
- });
- //可以写成
- $provide.factory('myDate', function(){
- return new Date();
- });
- //调用:
- app.controller('MainCtrl', function($scope, myDate) {
- $scope.myDate = myDate; //current date
- });
直接第二个参数就是$get要对应的函数实现,代码简单了很多有没有?!
service
这时候我又来劲儿了,我不仅就想定义个$get
,里面我还就返回个new出来的已有js类,三哥service
闪亮登场~
- $provide.provider('myDate', {
- $get: function() {
- return new Date();
- }
- });
- //可以写成
- $provide.factory('myDate', function(){
- return new Date();
- });
- //可以写成
- $provide.service('myDate', Date);
对于这种需求,代码更简洁了是不是~~
value vs. constant
更直接的需求来了,我只想定义个$get
,而且就返回个常量~
这时候value
和constant
都可以做到~
- $provide.value('pageCount', 7);
- $provide.constant('pageCount', 7);
兄弟俩功能一样?双胞胎?那怎么可能~
介绍区别前,先得把之前坐小板凳等着的decorator
叫出来~终于该出场了~
区别一:value
可以被修改,constant
一旦声明无法被修改
- $provide.decorator('pageCount', function($delegate) {
- return $delegate + 1;
- });
decorator
可以用来修改(修饰)已定义的provider们,除了constant
~
区别二:value
不可在config
里注入,constant
可以
- myApp.config(function(pageCount){
- //可以得到constant定义的'pageCount'
- });
关于config
,之后会专门介绍~
通过底层实现代码看关系~
- function provider(name, provider_) {
- if (isFunction(provider_)) {
- provider_ = providerInjector.instantiate(provider_);
- }
- if (!provider_.$get) {
- throw Error('Provider ' + name + ' must define $get factory method.');
- }
- return providerCache[name + providerSuffix] = provider_;
- }
- function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); }
- function service(name, constructor) {
- return factory(name, ['$injector', function($injector) {
- return $injector.instantiate(constructor);
- }]);
- }
- function value(name, value) { return factory(name, valueFn(value)); }
- function constant(name, value) {
- providerCache[name] = value;
- instanceCache[name] = value;
- }
- function decorator(serviceName, decorFn) {
- var origProvider = providerInjector.get(serviceName + providerSuffix),
- orig$get = origProvider.$get;
- origProvider.$get = function() {
- var origInstance = instanceInjector.invoke(orig$get, origProvider);
- return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});
- };
- }
从上面的代码可以看出之前介绍的每种provider的特点,decorator
比较特殊,不算,除了constant
,另外几个最终调用的都是provider
~