简体   繁体   中英

$scope and $rootscope confusion

I don't understand why the output of this program is not

Global value is 4 

Child Instance of Function1 created :- 1

Child Instance of Function2 created :- 2

Child Instance of Function1 created :- 3

Child Instance of Function2 created :- 4

Plunker - http://plnkr.co/edit/HktvgxMM0g1WJG2oLjIN?p=preview

Thanks for the help.

The reason is because your second controller is referencing $rootScope on the view, while the first controller is referencing a local $scope on the view.

As the first controller has a local scope set, it will be what ever it was set to at the time. In your case 1 & 3 .

Your second controller however is referencing the same value (the $rootScope one). So at the time of instantiation each of the second controllers is outputting the value to the console at that time. However the view will only show the most recent $rootScope value (which is 4).


Just remember that $rootScope is the same for everything that uses it. So if two places add 1 to a rootScope value, then the value will ultimately have 2 added to it.

Also when you use {{Counter}} in your view, this is what happens. Angular looks up the scope hierarchy for the first found Counter value. For your second controller it cannot find a local $scope that has a Counter value, so it then checks the $rootScope next, which is where it finds the reference.

Scope is an instance of controller

Everytime you declare a controller in view it'll create scope for own.

In Function1 you increase Counter in $rooscope and also assign in controller scope's Counter .

$rootScope.Counter = (($rootScope.Counter || 0) + 1);
$scope.Counter = $rootScope.Counter;

And If variable of both parent and child is same name always child will get executed.

That's why in view value of Counter will be child's scope Counter .

In Function2 you increase counter in rootScope but didn't use local scope so Counter will be rootScope without any doubt.

$rootScope.Counter = (($rootScope.Counter || 0) + 1);

So Simmulation will be

Function1 : 

rootScope : 1
Scope : 1 // will print this 


Function2

rootScope : 2 // will print this



Function1 : 

rootScope : 3
Scope : 3 // will print this


Function2

rootScope : 4 // will print this

As for two binding wherever you use rootScope 's Counter it'll print 4 as current value in Counter in rootScope is 4.

If you wanna get your desired answer , You have to assign value in child Scope's counter in Function2 like Function1

Like this

$rootScope.Counter = (($rootScope.Counter || 0) + 1);
$scope.Counter = $rootScope.Counter;
$scope.ControllerName = "Function2";

PLUNKR

As it has been mentioned in earlier answers, $scope is created/injected into a new controller during its creation ( Function1 and Function2 in your case). Each $scope might be a grand or great ... great grand child of $rootScope , as you can tell by $scope.$id compared to $rootScope.$id .

If you want $scope to be a closer generation of child or grand child, you can create a $scope using $scope = $rootScope.$new() , but this is not very practical. If you use $rootScope.$new() to create $scope , you are guaranteed to have the same Counter value as the $rootScope has, not much else benefits gained this way, however.

You can understand it in this way $rootScope is top most scope and all the other scope (ie $scope) comes inside this. So incase you have to pass value between scope then you have to use $rootScope.

Note: function1 use local variable Counter where scope is within the controller. Ie each controller have there own scope. function2 use global variable Counter, because no global variable define.

In your case the (remember angular support two way binding, so whenever global value change it changes at all the places), The controllers get called in following order function1 -> function2 -> function1 -> function2.

When function1 get called first time $rootScope.Counter is not present so it initialize with one and assign the same to local variable 'Counter'.

so output look like
Global value is 1 
Child Instance of Function1 created :- 1

Child Instance of Function2 created :- 1

Child Instance of Function1 created :- NA // local scope for this is not created

Child Instance of Function2 created :- 1

Now function2 will get called. This increase global variable Counter to 2 and use it to display

so output look like
Global value is 2 
Child Instance of Function1 created :- 1

Child Instance of Function2 created :- 2

Child Instance of Function1 created :- NA // local scope for this is not created

Child Instance of Function2 created :- 2

Now function1 will get called again. This increase global variable Counter to 3 and assign it local variable.

so output look like
Global value is 3 
Child Instance of Function1 created :- 1

Child Instance of Function2 created :- 3

Child Instance of Function1 created :- 3 //Because rootScope already have counter variable with 2

Child Instance of Function2 created :- 3

and finally function2 get called again, This increase global variable Counter to 4 and use it to display

so output look like
Global value is 4 
Child Instance of Function1 created :- 1

Child Instance of Function2 created :- 4

Child Instance of Function1 created :- 3

Child Instance of Function2 created :- 4

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