angular如何知道要注入哪些服务?

时间:2014-02-28 00:46:52

标签: angularjs

我对Angular如何知道注入哪些服务感到困惑。例如,假设我们创建了一个类似

的记录器服务
appModule.factory('logger', function(){
    return { /* Logger module here */ };
});

他们,如果在某个控制器中我想使用这项服务,我知道我会像以下一样使用它:

appModule.controller('MyController', function($scope, logger) { });

这让我感到困惑,因为我不知道Angular如何知道$scope引用控制器范围而logger引用了记录器服务。它验证名称os变量?那么它试图将变量的名称与一些可用的服务相匹配?

如果我们要添加第三个参数anotherParam,它会检查名为anotherParam的服务吗?

3 个答案:

答案 0 :(得分:3)

魔术由$injector.annotate完成:

  

<强>注释(FN);

     

返回函数请求注入的服务名称数组。注入器使用此API来确定在调用函数时需要将哪些服务注入到函数中。有三种方式,其中函数可以使用所需的依赖项进行注释。

第一种方法是从函数签名中提取参数的名称:

  

参数名称

     

最简单的形式是从函数的参数中提取依赖项。这是通过使用toString()方法将函数转换为字符串并提取参数名称来完成的。

     

<强>推断

     

在JavaScript中调用函数上的toString()会返回函数定义。然后可以解析定义并提取函数参数。注意:这不适用于缩小和混淆工具,因为这些工具会更改参数名称。

从源代码中,$ injector如何从函数中提取参数:

if (fn.length) {
  fnText = fn.toString().replace(STRIP_COMMENTS, '');
  argDecl = fnText.match(FN_ARGS);
  forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
    arg.replace(FN_ARG, function(all, underscore, name){
      $inject.push(name);
    });
  });
}

您可以在此处找到它:https://github.com/angular/angular.js/blob/v1.2.13/src/auto/injector.js#L77

答案 1 :(得分:2)

是的,注入是基于参数的名称,AngularJS使用通常称为内省的内容,因此它检查函数定义中参数的名称,然后查找它之前看到的服务。

要明确地将它们保存为字符串,以便在进行缩小操作时注入仍然有效(变量名称丢失,则有另一种语法)

appModule.controller("MyCtrl", ["$scope", function($scope) {}]);

^以这种方式给出一个他们不会被缩小的字符串列表和角度仍然可以确定如何适当地进行注入。请注意,如果您使用第二种方法,字符串的顺序必须与您希望注入的参数顺序相匹配,如果您不小心添加字符串但没有参数,则可能是一个问题,反之亦然。我相信有一个Grunt任务会为你照顾这个(ng-min可能不确定)

答案 2 :(得分:1)

简短回答是肯定的。

为了更清楚,你可以写

appModule.controller('MyController', ["$scope", "logger", function($scope, logger) { }]);

如果你有一个js函数

那么神奇的角度使用是
var f = function(a, b, c, d) {};
console.log(f.toString());
// Output
// function (a, b, c, d) { [...] } 

Angular仍然可以获取这些信息,即使您没有手动提及它们。

查看更多http://docs.angularjs.org/guide/di