Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding dependency injection in AngularJS controllers

Just learning dependency injection, and I think I'm starting to understand it.

Please tell me if I'm on the right track...

E.g.: Are these two equivalent?

/* injection method */
function <controller_name>($scope) {}
<controller_name>.$inject = ['$scope'];

/* other method */
var app = angular.module('myApp');
app.controller(<controller_name>, function($scope) {});
like image 306
user2283066 Avatar asked May 20 '13 22:05

user2283066


2 Answers

First a little clarification:

For dependency injection, it doesn't matter whether you declare a controller using a global function or as the argument of module.controller(...) method. Dependency injector is only concerned about the function itself. So what you're actually asking about is the equivalence of those two:

// First

function MyController($scope) {}

MyController.$inject = [ '$scope '];

// Second

function($scope) {}

And because whether the controller function is anonymous or not also doesn't matter for the injector, the above two can just as well be:

// First

function MyController($scope) {}

MyController.$inject = [ '$scope '];

// Second

function MyController($scope) {}

Now it's clear that the only difference between your two controllers is the presence of the $inject property in one of them.

And here's the actual answer to your question:

These two controllers are almost the same. Both will receive the $scope as the argument and will function the same. However, if you decide to minify your code later, only the version with $inject array set on it will work properly. This is because if you don't specify the $inject array nor use the inline annotation approach (http://docs.angularjs.org/guide/di#inlineannotation), the only way for the injector to find out which dependencies you were interested in is to check the names of your function arguments (treating them as service IDs). But minification would name those arguments randomly thus removing the chance to recognize dependencies this way.

So if you're going to minify your code, you have to specify the dependencies explicitly using $inject array or inline annotation, otherwise, any version will work just as good.

like image 158
mirrormx Avatar answered Sep 28 '22 07:09

mirrormx


If you're going to use the module.controller method, the equivalent to your first example would be:

var app = angular.module('myApp');
app.controller(<controller_name>, ['$scope', function($scope) {}]);

Notice that this way we're passing the $inject string along with the function, so that if it later gets minimized it will still work.

like image 27
Karen Zilles Avatar answered Sep 28 '22 06:09

Karen Zilles