angular 1.5.8 注入annotate方式解析
先看使用案例:
1 | // 创建myModule模块、注册服务 |
angular.module函数
核心angular.module方法是通过执行factory函数返回factory内部的函数,调用
angular.module(‘myModule’, [])方法的时候已经是执行最内部的函数了,最终演变为
modules[“myModule”] = factory(); 返回moduleInstance。
1 | function setupModuleLoader(window) { |
module的service函数
module里包含了一系列方法:provider,factory,service,value,constant,decorator,
animation,filter,controller,directive,component。
value和constance 是invokeLater函数的返回值,其他是invokeLaterAndSetModuleName函数的
返回值。
service函数主要作用就是把函数放入providerCache
service内部 就是实例化传入的函数
最终调用invoke函数的时候 通过$injectorProvider 去调用instantiate函数把service中的function当作参数传入1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42service: invokeLaterAndSetModuleName('$provide', 'service');
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
//强制返回一个方法而已
function enforceReturnValue(name, factory) {
return function enforcedReturnValue() {
var result = instanceInjector.invoke(factory, this);
if (isUndefined(result)) {
throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
}
return result;
};
}
//最终放入provider
//此处的factoryFn就是 上面的第二个参数 数组了
function factory(name, factoryFn, enforce) {
return provider(name, {
//undefind !== false 为true
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
}
//返回实例化的 provider
//比如在定义ng模块的时候函数内部用到的链式调用
function provider(name, provider_) {
assertNotHasOwnProperty(name, 'service');
if (isFunction(provider_) || isArray(provider_)) {
provider_ = providerInjector.instantiate(provider_);
}
//没有定义$get函数会报错
if (!provider_.$get) {
throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name);
}
return providerCache[name + providerSuffix] = provider_;
}
放入moduleInstance的invokeQueue中
angular.injector函数
angular.injector函数返回一个instanceInjector
调用invoke函数 通过参数解析函数 annotate ,此函数可以直接把$inject属性当作参数传入
核心就是获取$provide 缓存
通过$provide 的providerCache 去获取 Provider
annotate函数在injectionArgs函数中被调用
返回注入的参数后 继续调用getService 去providerCache里去找 provider
instanceInjector.invoke函数
invoke函数会调用传入的函数 ,如果函数包含$inject属性,那么会直接把$inject属性通过getService获取
该属性返回值,然后当作参数传入函数。
1 |
|
createInjector 函数整体返回
1 | return { |