AngularJS - DI系统是如何知道参数的名字的?

AngularJS - How does the DI system know of the name of the arguments?

本文关键字:参数 何知道 DI 系统 AngularJS      更新时间:2023-09-26

直接从官方网站的例子:

function PhoneListCtrl ($scope, $http) {
    $http.get('phones/phones.json').success(function(data) {
        $scope.phones = data;
    });
    $scope.orderProp = 'age';
}

$scope$http参数是唯一标识符,用于在DI系统中定位相应的AngularJS服务。那么,DI系统究竟如何检索这些参数的变量名呢?

var FN_ARGS = /^function's*[^'(]*'('s*([^')]*)')/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^'s*(_?)('S+?)'1's*$/;
var STRIP_COMMENTS = /(('/'/.*$)|('/'*['s'S]*?'*'/))/mg;
function annotate(fn){
    var $inject
    if (!($inject = fn.$inject)) {
        $inject = [];
        fnText = fn.toString().replace(STRIP_COMMENTS, '');
        argDecl = fnText.match(FN_ARGS);
        angular.forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
            arg.replace(FN_ARG, function(all, underscore, name){
                $inject.push(name);
            });
        });
        fn.$inject = $inject;
    }
    return fn.$inject;
}

Demo: Fiddle(查看控制台);

步骤:
1. 在函数中调用toString返回函数源
2. 使用regex
删除所有注释3.使用regex

从源代码中提取参数

直接从源代码@GitHub:

的参数中提取依赖项是最简单的形式这个函数。这是通过将函数转换为字符串来实现的使用toString()方法提取参数名称。
// Given
function MyController($scope, $route) {
    // ...
}
// Then
expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);

和注释函数

function annotate(fn) {
  var $inject,
  fnText,
  argDecl,
  last;
  if (typeof fn == 'function') {
    if (!($inject = fn.$inject)) {
      $inject = [];
      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);
      });
    });
    fn.$inject = $inject;
    }
  } else if (isArray(fn)) {
    last = fn.length - 1;
    assertArgFn(fn[last], 'fn')
    $inject = fn.slice(0, last);
  } else {
    assertArgFn(fn, 'fn', true);
  }
  return $inject;
}