Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does angular's controller method make $scope available to my function argument

I am looking for a pseudo code answer, or conceptual answer please.


After programming for a number of years I have never created a class method that receives a function argument such that the caller of the method automatically gets access to 'invisible' properties.

If I try to access $scope outside of my my_app.controller(...) method, I get an error so I know it's not global; if I try to access it from my_app.$scope or angular.$scope I get undefined.

So how does my function parameter get access to it:

    my_app.controller('my_controller' , function( $scope , ... ) { ... }

UPDATE (as I am learning):

  // javascript
  var my_class =   function( argument_A )                 
                       { this.some_prop = argument_A ;        

                         this.some_method = function( argument_B ) 
                           { console.log( argument_B ) ; // function(boo)
                           } ;
                       } ;

  var my_instance = new my_class( "my_string" ) ;

  var my_function_argument = function( boo ){ } ;
  my_instance.some_method( my_function_argument ) ; 
like image 538
dsdsdsdsd Avatar asked Feb 18 '16 20:02

dsdsdsdsd


People also ask

How do you access $scope in console?

scope(); $('#elementId'). scope(). $apply(); Another easy way to access a DOM element from the console (as jm mentioned) is to click on it in the 'elements' tab, and it automatically gets stored as $0 .

What does $scope mean in AngularJS?

The $scope in an AngularJS is a built-in object, which contains application data and methods. You can create properties to a $scope object inside a controller function and assign a value or function to it. The $scope is glue between a controller and view (HTML).

What is $scope in JavaScript?

Scope in JavaScript refers to the current context of code, which determines the accessibility of variables to JavaScript. The two types of scope are local and global: Global variables are those declared outside of a block. Local variables are those declared inside of a block.

What is $scope angular 8?

AngularJS Scope The scope is the binding part between the HTML (view) and the JavaScript (controller). The scope is an object with the available properties and methods. The scope is available for both the view and the controller.


1 Answers

Functions Are First Class Citizens

In JavaScript and other modern languages (Scala, Haskell, LISP, etc.), functions are treated as first-class citizens. Specifically, this means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures. Some programming language theorists require support for anonymous functions (function literals) as well. In languages with first-class functions, the names of functions do not have any special status; they are treated like ordinary variables with a function type.1

The above example can be re-factored as:

var myController = function ($scope, ... ) {
     console.log($scope);
     $scope.message = "Hello world"
};

my_app.controller('my_controller' , myController );

In this case the .controller method stores the myController object in the cache of the AngularJS $controllerProvider service. I.e. cache["my_controller"] = myController;

Later when the $compile service encounters a directive that needs a controller:

<div ng-controller="my_controller">
    {{message}}
</div>

The $compile service creates a new scope, retrieves the myController function from the $controller service cache, and invokes the function with the new scope as the first argument of the function.

The $compile service also creates a $watch listening function that tracks the $scope.message variable. On each digest cycle, if $scope.message has changed, the DOM is updated appropriately.

In the examples from the question:

//These are function invocations, the variable must be defined

console.log( boo )              ; //    ERROR: boo is not defined
my_instance.some_method( boo )  ; //    ERROR: boo is not defined

The last form uses an anonymous function literal (or function expression). The anonymous function is an object passed as an argument to the method named .some_method.

//The anonymous function is an object passed as an argument
//boo is a parameter to be supplied when the function is invoked

my_instance.some_method( function( boo ) { } ) ; // NO ERROR

For more information on function literals, see MDN JavaScript Reference -- function expression.


Dependency Injection and Connecting Arguments by Name

Normally in JavaScript, function arguments are connected by position. In the AngularJS framework, function arguments are injected by name. How is that done?

From the Docs:

Inference

In JavaScript calling toString() on a function returns the function definition. The definition can then be parsed and the function arguments can be extracted.

-- AngularJS $injector Service API Reference -- Inference

So in the example:

my_app.controller('my_controller' , function( $scope , ... ) { ... }

The $injector service does a toString() on the controller construction function and parses it. The service detects that $scope is the first argument of the function and uses that knowledge to invoke the function correctly.

You can see fn.toString() being used here in the source code.

like image 135
georgeawg Avatar answered Oct 23 '22 03:10

georgeawg