Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Angular Controller need "$scope"

I have normally learned that function implementation can have any name for function arguments as long as it is supplied in the right order. This makes the function abstracted from the outside world and the local names have no effect on the output . Implementer has all the rights for local variables. However in Angular JS, it seems to counter intuitive to have something like:

function Controller($scope)
{
    $scope.name = "Something";
}

If I put "bar" there instead "$scope" I get an error. This is not the normal function that we are used to . I believe it something to do with DI, but can anyone explain this concept ? I find it hard to call this a "function" because it is dependent on the outside world - especially the argument name .

If DI is the real reason , can any one let me know how does it get invoked ? Normally I can think of DI doing good when I want to mock an object for test case. In this case what role does DI play ?

In the normal scenarios of DI that I have come across , the argument that gets passed, does a service for the function like say foo displayTime(clock) { clock.something } . Time is just a service for the the function . However here I find that , the $scope and the framework seems to do the magic with the function just being declarative way of expressing the logic .

Edit : Apparently JS minify breaks this functionality and we need to do like in How do the function argument names in Angular.js objects connect to other objects?

like image 740
Nishant Avatar asked May 22 '14 13:05

Nishant


1 Answers

One way to define a controller is like so:

myApp.controller("TestController", ['$scope', function(bar) {
   // now "bar" is actually the scope variable
}]);

The whole reason that angular works like this is because of the way it does dependency injection. Basically it looks for the dependancies (eg $scope) and it tries to inject them based on name of the variable. That means if you name $scope something different then it tries to inject that other item instead. bar isn't something that angular knows how to inject so you are going to get an undefined value instead of the $scope you were expecting.

My example above works because I used an array to separate out the names of the variables that are going to be injected from the variables themselves. Now you don't have to use the word $scope but you must keep the variables in the same order. The whole concept of DI is too complicated to explain in a short post so I recommend reading more about it on angular's site here: https://docs.angularjs.org/tutorial/step_05

The Point of DI (in angular)

In case you are wondering - why go to all this trouble? Why not just automatically inject $scope into the first variable that you have in the list? The answer is - flexibility & customization. With angular, you can define your services and factories, then inject them into your controllers. This gives you the power to define shared routines, objects or even custom controls and then use them across as many controllers as you want. Without DI - none of this would be possible. Again, these are pretty complicated concepts so I recommend starting with a leap of faith that "it works", learning about services, then later you can go back and read more about it. At that point I think DI should make a whole lot more sense!

Best of luck!

like image 57
drew_w Avatar answered Oct 11 '22 22:10

drew_w