简体   繁体   中英

angularjs, how $scope parameter works behind the scenes?

Controllers take as a second parameter an anonymous function.

I have two examples of controllers, one with the anonymous function taking as parameter nothing , and the second taking the $scope object.

How angularjs "behind the scenes" can detect that my anonymous function has an argument or not? And how can I mimic that in a custom js method?

controller('ctrl',function(){
        console.log( arguments[0] ); // ->> undefined
    });

vs

controller('ctrl',function($scope){
        console.log( arguments[0] ); // ->> js object
    });

A pseudo code that I`m thinking is like this:

( if F has parameters ) F.bind($scope) // or F.call(....)

As documented Here

Angular will instantiate a new Controller object, using the specified Controller's constructor function. A new child scope will be created and made available as an injectable parameter to the Controller's constructor function as $scope.

So the first argument passed to the Controller's constructor function is the child scope instance $scope. Since the arguments object is an Array-like object corresponding to the arguments passed to a function, printing arguments[0] will print the first passed argument (ie $scope).

It is how angular's Dependency Injection works: it looks at the args names, then looks it up to know what to inject.

You can find the specific code for this here:

https://github.com/angular/angular.js/blob/master/src/auto/injector.js#L72

Angular gets the names of the objects to inject from one of three places (only the first of these that exists is used):

  • The $inject attribute of the function
  • If instead of a function you give it an array then the function should be the last element of the array and the injectable names are all the others.
  • Otherwise it inspects the arguments the function is actually expecting by calling toString() on the function and extracting the names from that.

Once it has a list of names the injector will find objects first in a mapping object that may be passed to the injector and then in the objects that have been registered in the available angular modules. Again the first matching object is used, so the code to invoke a controller passes a unique $scope object to the injector for each controller but most other names you can use such as for services are singletons and the same object is reused each time.

You can use the injector yourself:

var injector = angular.injector();
function MyFunction(something) { ... }
injector.invoke(MyFunction, this, { something: anObject });

See https://docs.angularjs.org/api/auto/service/ $injector

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM