3

I am a beginner to angular JS and I found this code in the tutorial.

var phonecatApp = angular.module('phonecatApp', []);

phonecatApp.controller('PhoneListCtrl', function($scope) {
  $scope.phones = [
    {'name': 'Nexus S',
     'snippet': 'Fast just got faster with Nexus S.'},
    {'name': 'Motorola XOOM™ with Wi-Fi',
     'snippet': 'The Next, Next Generation tablet.'},
    {'name': 'MOTOROLA XOOM™',
     'snippet': 'The Next, Next Generation tablet.'}
  ];
});

This code is working fine but I want to know how the variable scope of $scope works. From the code, it seems the $scope is a local variable and its scope is limited only to the function.

Then why cant I change the name of the $scope variable? If I change the variable name in all occurrences inside the function, it doesn't seems to work

3
  • $scope is where you hold values and functions that you want to be visible to the user. Anything you want to bind to an element, you add to $scope. Read about the digest cycle if you want to learn more about this. > What surprises me is the that when the name of the variable $scope change, the code doesn't seems to work. This is because angular uses dependency injection all over the place. Commented Mar 9, 2015 at 16:31
  • my doubt is more javascript than angular js. How does the value of variable $scope is obtained outside the function block ? its not returning the $scope also $scope is not global Commented Mar 9, 2015 at 16:37
  • Outside angular or controller function ? Commented Mar 9, 2015 at 16:38

3 Answers 3

2

Angular uses dependency injection. $scope is an injected value. It is essentially an object containing all of the ng- references inside of the relative controller for that module.

"A module is a collection of services, directives, controllers, filters, and configuration information." -angular source

When you access something from the collection a module contains, the scope of that access is injected. For example, when a module is created, the module creates a controller property

/**
* @ngdoc method
* @name angular.Module#controller
* @module ng
* @param {string|Object} name Controller name, or an object map of controllers where the
 *    keys are the names and the values are the constructors.
 * @param {Function} constructor Controller constructor function.
 * @description
 * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
 */
 controller: invokeLater('$controllerProvider', 'register'),

This property is registered with the controllerProvider.

The controller is injectable (and supports bracket notation) with the following >locals:
*
* * $scope - Current scope associated with the element

So when you are using this code

phonecatApp.controller('PhoneListCtrl', function($scope){

What you are doing is accessing the 'PhoneListCtrl controller from the controller provider, and then the function provided is called with the associated scope stored with the PhoneListCtrl for that module.

With specific regards to the variable name $scope, the reason that angular can tell if you are using this "keyword" is through a regex process. If you use .toString() on a function it will convert the entire thing to a string, and you can then parse it to see what was in the function. Angular does this,

"The simplest form is to extract the dependencies from the arguments of the function. This is done by converting the function into a string using toString() method and extracting the argument names."

The regex is defined in angular as var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; You can test using this at https://regex101.com/r/qL4gM8/1

enter image description here

So that is how Angular knows that you used the variable $scope in your function parameters.

Sign up to request clarification or add additional context in comments.

2 Comments

The last part of your answer cleared my doubt. Thank you very much.
@MS, just to add to Travis's answer. This kind of regex-matching of of function parameters does not withstand minification, which is why explicit annotation is needed when minifying the code
2

From AngularJS Docs:

Scope is the glue between application controller and the view... Both controllers and directives have reference to the scope, but not to each other.

$scope is created by angular and injected (dependency injection) into your controller function by refference.

Think about this simple javascript sample an then expand your thoughts to AngularJS

(function() {
     // var myscope is not global. it's in the closure
     // of my anonymous function
     var myscope = {
        "samplekey" : "samplevalue"
     }

     // .... You can do anything with scope

     // Imagine this function as your controller
     function myController($scope) {
        // Here I can work with $scope variable
        $scope.data = { "anotherkey" : "anothervalue" };
        console.log($scope.samplekey); // It works fine
     }

     // inject myscope into the controller function
     myController(myscope);

     // I can access the new property added to myscope variable
     // by the controller function (maybe I can use it in a view).  
     console.log(myscope.data.anotherkey); // anothervalue 

}());

You can use any variable you want as scope in AngularJS as well. But you have to specify that the variable you created is referencing the scope variable.

phonecatApp.controller('PhoneListCtrl',['$scope', function(varAsScope) {
  varAsScope.phones = [
    {'name': 'Nexus S', 'snippet': 'Fast just got faster with Nexus S.'},
    {'name': 'Motorola XOOM™ with Wi-Fi', 'snippet': 'The Next, Next Generation tablet.'},
    {'name': 'MOTOROLA XOOM™', 'snippet': 'The Next, Next Generation tablet.'}
  ];
}]);

Here is a Working Example

4 Comments

my doubt is more javascript than angular js. How does the value of variable $scope is obtained outside the function block ? its not returning the $scope also $scope is not global
I've updated my answer trying to explain how Angular inject a scope variable into your controller
If I change the name of the variable $scope inside your function. It still works fine. But in angular, i doesn't work. And that is my doubt. Why cant I change a variable name inside the funciton scope in angular js
could u please make it the other way around? .i.e. can you make your code such a way that the $scope variable is not modifiable. or if I modify the $scope variable in your code, it works differently ?
0

Everything in angular starts with $ is a service here scope is also the the service which binds view with controller and allow you to use TWO WAY BINDING.

Yes $scope is limited to a particular component we can say directive or the controller.But we have father's of scope as well $rootScope.

So you can use $rootScope as a service for global stuff.

Hope it clears your doubt.

Few links that will help are follows :-

Github(Best resource)

Doc

4 Comments

my doubt is more javascript than angular. How does the value of variable $scope is obtained outside the function block ? its not returning the $scope also $scope is not global
outside angular or just single controller ?
Simple send $scope to other function as a variable if you are calling it fron inside the angular side for example i want to call add() function i can call it like add($scope) and send the simple scope and extract its value :-)
I am not sure whether you have understood my question. Suppose we have a function function fun(a){ a = "Hello"}, there is now way the value of variable a is obtained outside the scope of the function. But in the example shown value is obtained outside the function. Also, inside the function the variable name doesn't matter. i.e. function fun(b){b="Hello'} should also work. But in the above example, if we change the $scope to say $scope2 in all places inside the function, it dosen't seems to work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.