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 ) ;
While you are creating a function and passing
dependency
name inside function parameter, in that case angular creates an object for each dependency by resolving that dependency from its DI container. This kind of dependency injection technique known asconstructor function
(there are two more DI techniques).When you inject controller on DOM using
ng-controller
directive at that time function is passed to$controllerProvider
'sregister
function. controller function is known as factory function. Which will get passed with dependency as parameter.$injector
service get each of dependency from function, and do$injector.get
to return out what ever dependency is registered in DI container. While doing returning$scope
dependency it creates out newscope
fromrootScope
using$rootScope.$new(isolate, parent)
method.$new
method takes two parameter 1st one asbool
& 2nd one asparentScope
parameter. Other dependency directly taken out from register component to module.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:
In this case the
.controller
method stores themyController
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:The
$compile
service creates a new scope, retrieves themyController
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:
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
.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:
-- AngularJS $injector Service API Reference -- Inference
So in the example:
The
$injector
service does atoString()
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.