2013-03-07 4 views
21

Esempio direttamente dal sito ufficiale:AngularJS - Come fa il sistema DI a conoscere il nome degli argomenti?

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

    $scope.orderProp = 'age'; 
} 

I $scope e $http argomenti sono identificatori univoci per la localizzazione di servizi corrispondenti AngularJS all'interno del sistema DI. Quindi, in che modo il sistema DI recupera il nome della variabile di questi argomenti, esattamente?

risposta

31

Questa è la versione tagliata verso il basso di modo

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

Dimostrazione: Fiddle (Vedi la console);

Passi: 1. Richiamo
toString in funzione restituisce la fonte funzione di
2. Rimuovere tutti i commenti utilizzando espressioni regolari
3. Estrarre gli argomenti dalla sorgente utilizzando regex

9

direttamente dalla fonte @GitHub:

La forma più semplice è quello di estrarre le dipendenze dagli argomenti del la funzione. Ciò avviene convertendo la funzione in una stringa utilizzando il metodo toString() ed estraendo i nomi degli argomenti.

// Given 
function MyController($scope, $route) { 
    // ... 
} 
// Then 
expect(injector.annotate(MyController)).toEqual(['$scope', '$route']); 

E la funzione di annotazione

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

come visto nel braccio 45 e successivamente

Problemi correlati