AngularJS应用程序依赖于$ injector服务来在控制器,指令或其他可注入的东西中注入其他内置或自定义服务,但是$ injector服务如何注入自身,就像:
app.controller(function($injector,$scope){
//...
});
答案 0 :(得分:3)
调试为angular的源代码,每当angular编译一个具有ng-controller
的元素时,它就会调用此函数来实例化控制器并注入所有依赖项:
controllerInstance = $controller(controller, locals);
在$controller
方法中,它调用此方法
instance = $injector.instantiate(expression, locals);
根据表达式实例化控制器,在您的情况下为function ($injector,$scope){}
:
反过来调用invoke
,请注意以下代码段:
for(i = 0, length = $inject.length; i < length; i++) {
key = $inject[i];
if (typeof key !== 'string') {
throw $injectorMinErr('itkn',
'Incorrect injection token! Expected service name as string, got {0}', key);
}
args.push(
locals && locals.hasOwnProperty(key)
? locals[key]
: getService(key)
);
}
此循环用于创建所有依赖项并存储在args
数组中。对于每个循环,它首先检查locals
(包含$scope
,$element
,$attr
等当前元素。要注意的重要函数是getService(key)
:
function getService(serviceName) {
if (cache.hasOwnProperty(serviceName)) {
if (cache[serviceName] === INSTANTIATING) {
throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));
}
return cache[serviceName]; //angular run to this line for $injector service
} else {
try {
path.unshift(serviceName);
cache[serviceName] = INSTANTIATING;
return cache[serviceName] = factory(serviceName);
} catch (err) {
if (cache[serviceName] === INSTANTIATING) {
delete cache[serviceName];
}
throw err;
} finally {
path.shift();
}
}
}
如果是$injector
服务,当angular初始化模块时,它会创建$injector
并存储在此cache
中。
这意味着$injector
不会自我注入,$injector
只是此服务cache
中的另一项服务。每当角度需要注入服务时,角度将在此cache
中查找,如果服务不存在,则角度将创建它。 $injector
是此cache