21

公式サイトからの例:

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

    $scope.orderProp = 'age';
}

$scopeおよび$http引数は、DI システム内で対応する AngularJS サービスを見つけるための一意の識別子です。では、DI システムはこれらの引数の変数名を正確にどのように取得するのでしょうか?

4

2 に答える 2

33

これは方法の縮小版です

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;
}

デモ: Fiddle (コンソールを参照);

手順:
1. 関数を呼び出すtoStringと関数ソースが返されます
2. 正規表現を使用してすべてのコメントを削除します
3. 正規表現を使用してソースから引数を抽出します

于 2013-03-07T12:07:27.637 に答える
9

ソース@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;
}

45行目以降に見られるように

于 2013-03-07T11:59:25.143 に答える