简体   繁体   English

$ scope和$ rootscope的混淆

[英]$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 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. 原因是因为您的第二个控制器在视图上引用$rootScope ,而第一个控制器在视图上引用本地$scope

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 . 在您的情况13

Your second controller however is referencing the same value (the $rootScope one). 但是,您的第二个控制器引用了相同的值( $rootScope一个)。 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). 但是,该视图将仅显示最新的$rootScope值(即4)。


Just remember that $rootScope is the same for everything that uses it. 只要记住$rootScope对于使用它的所有东西都是一样的。 So if two places add 1 to a rootScope value, then the value will ultimately have 2 added to it. 因此,如果两个位置向rootScope值添加1,则该值最终将添加2。

Also when you use {{Counter}} in your view, this is what happens. 同样,当您在视图中使用{{Counter}}时,也会发生这种情况。 Angular looks up the scope hierarchy for the first found Counter value. Angular查找第一个找到的Counter值的范围层次结构。 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. 对于您的第二个控制器,它找不到具有Counter值的本地$scope ,因此它随后检查$rootScope ,这是它在其中找到引用的地方。

Scope is an instance of controller Scopecontroller的实例

Everytime you declare a controller in view it'll create scope for own. 每次在视图中声明controller ,它都会为自己创建scope

In Function1 you increase Counter in $rooscope and also assign in controller scope's Counter . Function1您可以在$rooscope增加Counter ,还可以在控制器作用域的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 . 因此,鉴于Counter值将是孩子的范围Counter

In Function2 you increase counter in rootScope but didn't use local scope so Counter will be rootScope without any doubt. Function2您可以在rootScope增加counter,但是没有使用本地范围,因此Counter毫无疑问将是rootScope

$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. 至于两个绑定,无论您在何处使用rootScopeCounter它将在rootScopeCounter当前值为4时显示4。

If you wanna get your desired answer , You have to assign value in child Scope's counter in Function2 like Function1 如果要获得所需的答案,则必须在Function2子作用域计数器中分配值,例如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). 正如前面的答案中提到的那样, $scope是在其创建过程中创建/注入到新的控制器中的(在您的情况下为Function1和Function2 )。 Each $scope might be a grand or great ... great grand child of $rootScope , as you can tell by $scope.$id compared to $rootScope.$id . 每个$scope可能是$rootScope一个伟大的或伟大的...伟大的子孙,就像$rootScope $scope.$id$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. 如果希望$scope是更近代的子代或大子代,则可以使用$scope = $rootScope.$new()创建$ scope,但这不是很实际。 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. 如果使用$rootScope.$new()创建$scope ,则可以保证具有与$rootScope相同的Counter值,但是通过这种方式没有太多其他好处。

You can understand it in this way $rootScope is top most scope and all the other scope (ie $scope) comes inside this. 您可以这样理解它:$ rootScope是最主要的作用域,而所有其他作用域(即$ scope)都位于此作用域之内。 So incase you have to pass value between scope then you have to use $rootScope. 因此,如果必须在范围之间传递值,则必须使用$ rootScope。

Note: function1 use local variable Counter where scope is within the controller. 注意:function1使用局部变量Counter,作用域在控制器内。 Ie each controller have there own scope. 即每个控制器都有自己的作用域。 function2 use global variable Counter, because no global variable define. function2使用全局变量Counter,因为没有全局变量定义。

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. 在您的情况下(请记住角度支持双向绑定,因此,每当全局值更改时,它都会在所有位置更改),按以下顺序调用控制器: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'. 第一次调用function1时,由于不存在$rootScope.Counter ,因此将其初始化为一个并将其分配给本地变量'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. 现在function2将被调用。 This increase global variable Counter to 2 and use it to display 将全局变量Counter增加到2并使用它来显示

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. 现在function1将再次被调用。 This increase global variable Counter to 3 and assign it local variable. 这会将全局变量Counter增加到3并为其分配局部变量。

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 最后再次调用function2,这会将全局变量Counter增加到4并使用它来显示

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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