在前面介绍angular中依赖注入相关的概念和细节时,非常多次提到了provider
这个概念,每次提到都会让大家再等等,再等等。现在再也等不了啦,从本篇文章开始就会陆续介绍provider
和一些基于provider
的高层方法,比如service
,factory
等等。
provider是什么?
通过对象声明provider
首先,我们来看看provider
是什么。在angular中,provider
就是知道如何处理依赖关系的一类对象。为啥说是一类对象呢,因为只要一个对象实现了provider
规定的契约,那么该对象就可以被称作provider
。这个契约也非常的简单:提供一个带有返回值的$get
方法即可。
比如下面的对象就是符合要求的provider
:
{
$get: function() {
return 'aConstant';
}
}
上面的对象定义了一个$get
方法,该方法返回了一个字符串作为返回值。
现在,我们定义了一个最简单的provider
,该如何把这个provider
注册到模块中呢?没错,还是通过module
实例提供的provider
方法:
var app = angular.module('test', []);
// 通过provider提供一个常量的获取方法
app.provider('a', {
$get: function() {
return 'aConstant';
}
});
// 直接通过constant定义一个常量
app.constant('b', 'bConstant');
在上述代码中,我们分别使用provider
和constant
方法定义了常量。比较一下两种方法,看看他们有什么区别?可能会有同学说不就是定义一个常量,有必要大费周章吗?确实,使用provider
来定义常量从步骤上而言会繁琐一些,但是它也增加了代码的灵活性不是吗?在计算机领域,有一句名言:”计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决”。这句话放在这里也同样试用,如果因为种种原因常量的定义不能在直接在代码中确定,那么将这个定义的过程延迟到$get
方法中不就是一种合理的解决方案吗?这里provider
的作用就是提供这一间接的中间层。
现在我们回头看看module
类型中是如何定义provider
方法的:
provider: invokeLaterAndSetModuleName('$provide', 'provider')
// invokeLaterAndSetModuleName本身也是一个函数,返回另一个函数
function invokeLaterAndSetModuleName(provider, method) {
return function(recipeName, factoryFunction) {
if (factoryFunction && isFunction(factoryFunction)) factoryFunction.