$ injector服务器如何在AngularJS中注入自身

时间:2014-04-20 09:14:43

标签: angularjs angularjs-service

AngularJS应用程序依赖于$ injector服务来在控制器,指令或其他可注入的东西中注入其他内置或自定义服务,但是$ injector服务如何注入自身,就像:

app.controller(function($injector,$scope){

//...

});

1 个答案:

答案 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

中的首批服务之一