M S
M S

Reputation: 4093

How variable scope of $scope in angular js works?

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

Upvotes: 3

Views: 227

Answers (3)

Travis J
Travis J

Reputation: 82327

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.

Upvotes: 2

nanndoj
nanndoj

Reputation: 6770

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

Upvotes: 2

squiroid
squiroid

Reputation: 14037

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

Upvotes: 0

Related Questions