Confused about the inconsistency of AngularJS injections

I am new to angular.js and have gone through several tutorials, including all of them at codeschool . I found them very useful and learned a lot. But now that I’ve finished my “introduction” and I’m trying to use it in some things, I find some confusing discrepancies, primarily “dependency injection”.

In the tutorials that I took, dependencies for services were implemented as follows:

 app.controller('name', [ $http, $scope, function($http, $scope) { // .. code ... // }]); 

It seems strange to me, but it still works. I was confused as to why [] did not end before the function (I assume this is what you call the "callback" function in javascript?). I expected it to be more like require.js , wherever it is ...

 app.controller('name', [ '$http', '$scope' ], function($http, $scope) { }); 

However, then I started looking at angular examples and demos on the Internet, and I found that it was consistent. For example, consider the following links:

In each of them, I see a dependency injection, used as follows:

 app.controller('name', function($http, AdvancedGithubUser) { }); app.controller('name', function($scope){ }); function controllerName($scope) { }; 

They completely bypass the syntax of array , and all three are different. In one, it takes a type of object that is declared somewhere else, but I don't see any wiring to point to it.

In another case, it just has these objects.

And still in another, the "name" of the controller part is the name of the function, and I don't see anything that actually designates it as controller , but it is used that way in directives.

Can someone explain this to me? Now I am completely lost. This inconsistency makes it difficult to select methods.

+6
source share
3 answers

There are three ways to annotate function dependencies:

First: explicit and exact with parameter names:

 app.controller('ACtrl', function($scope, $http, $q) { //your stuff here }); 

This means that the function has parameter names that must correspond to the names of already registered services / providers. Caveat : if you minimize the file (uglify to save space), you will lose the parameter names, and therefore it will be broken - it will not work (it will complain).

The second method allows you to select the names of the services to enter as string literals (since the string literal is a value, it is never reduced):

 var myfunc = function($s, $http, $q) { //do your stuff here }; myfunc.$inject = ['$scope', '$http', '$q']; app.controller('ACtrl', myfunc); 

This means that Angular reads the $ injection property of the function and corresponds to the formal parameters not by name, but by value in the same position of the array. That way, $ scope will be in $ s, even if you shrink the file. If $ injection does not exist in this function, then you will return to the first and not recommended case.

The third is similar to the second (that is, it will indicate dependencies in rows and will resist guessing):

 var myfunc = function($s, $http, $q) { //do your stuff here } app.controller('ACtrl', ['$scope', '$http', '$q', myfunc]); 

Note that the last element of the array is a call function. It looks a little creepy, but it is consistent. Angular does this: if the controller is an array, the last element is exposed - it will be a function. The first elements (the remaining array) are processed exactly as if they were the value of $inject in the function.

Controllers and vendors must have a name to reference them - I used "ACtrl" as the name of the controller. This is not a function name, but an internal name for use in Dependency Injection (for providers) and more, such as ngRoute (for controllers).

The name declaration is the first border of the posting that you request. Using them in any of the three forms of Injection Dependency is the second link of such posting .

Remember : AdvancedGithubUser is a registered provider, equal to $http . The only difference is that $http is built into Angular, while AdvancedGithubUser is not. Characters starting with a dollar sign should be reserved for Angular, but this is not a requirement - just good practice. AdvancedGithubUser was created (in an external module) with something like:

 app.service('AdvancedGithubUser', AdvancedGithubUser); //being AdvancedGithubUser a constructor. 
+6
source

AND

 myApp.controller('ACtrl', ['$scope', function($scope) { }]) 

and

 myApp.controll('ACtrl', function($scope) { }); 

allowed. However, according to docs , it is recommended to use the first method (array notation).

"This avoids the creation of global functions for controllers, and also protects against minimization."

+4
source

You can use either direct dependency injection, as in your links, or named dependency injection (with an array).

I would recommend named syntax as a minimizer such as uglify will compress variable names. With an array, you name the object to enter, and then (the last parameter, function) that you use, so angular will still know which object you want after compressing the variables.

+1
source

Source: https://habr.com/ru/post/973052/


All Articles