简体   繁体   中英

Angular Service Injection

I am working on a trivial task (that I got working) which adds an an .active class to dom elements in a tab nav. Simple. Got it working by following https://stackoverflow.com/a/12306136/2068709 .

Reading over the answer provided and comparing their controller to example controllers on angular's website I came across something interesting that I don't quite understand.

On the AngularJS website, $scope and $location (and other services) are injected into the controller along with an anonymous function which defines the controller. But on the answer, the services are not injected , rather they are passed via the anonymous function. Why does this work? Shouldn't the service always be injected?

In terms of an example: Why does this

angular.module('controllers', [])
    .controller('NavigationController', ['$scope', '$location', function($scope, $location) { 
        $scope.isActive = function(route) {
            return route === $location.path();
        };
    }])

and this

angular.module('controllers', [])
    .controller('NavigationController', function($scope, $location) { 
        $scope.isActive = function(route) {
            return route === $location.path();
        };
    })

both work?

This may be trivial but its throwing my brain for a loop that I can't figure out.

The two examples are equivalent - they just make use of different syntax. The first example uses what they call "inline array annotation" (see here ). The purpose of this alternate syntax is just to allow a convenient way to make the injected variable names different than the name of the dependency.

So for example, if you wanted the variable names to be "s" and "l", then you could write:

angular.module('controllers', [])
    .controller('NavigationController', ['$scope', '$location', function(s, l) { 
        s.isActive = function(route) {
            return route === l.path();
        };
    }]);

Actually they are injected in both cases, the difference between those two cases is in the first scenario you define and name the dependency this could be useful if you minify your js code and that way you are declaring explicitly the dependency for examply it could be:

angular.module('controllers', [])
    .controller('NavigationController', ['$scope', '$location', function($s, $l) { 
        $s.isActive = function(route) {
            return route === $l.path();
        };
    }])

that way angular will know which dependency to inject on which parameter without looking at the naming for each parameter.

the other case you need to be explicit and declare which dependency you'll inject by setting up the name.

I hope that helps.

This is how angular handles code minification. by keeping strings intact it can keep mapping vars when they are renamed. if you take a look at the code of the controller https://github.com/angular/angular.js/blob/master/src/ng/controller.js#L48 you'll see that the constructor can accept both function and array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM