我使用$scope.$digest()
方法感到很困惑。据我所知,当我们调用$scope.$digest()
时,它不会更新父范围值,所以
它处理当前范围的所有观察者及其 儿童
,但是当我调用$scope.$digest()
时,它也会更新父范围,在这种情况下是$rootScope
。
在下面的例子中,我有一个演示。在$rootScope
我有一个名为value_on_root
的变量,所以每当我在输入上调用onchange
事件时,我调用一个角度函数,在其中我改变变量的值{{1 } file_src
上的$scope
也改变value_on_root
上的变量$rootScope
的值,所以当我调用$scope.$digest
时,更新会调用观察者$rootScope
也是。
查看此处的示例
答案 0 :(得分:2)
" $ digest循环由于调用$ scope而开始。$ digest()。假设您通过ng-click指令更改处理函数中的范围模型。在这种情况下,AngularJS通过调用$ digest()自动触发$ digest循环。当$ digest周期开始时,它会触发每个观察者。这些观察者检查范围模型的当前值是否与上次计算的值不同。如果是,则执行相应的侦听器函数。因此,如果您在视图中有任何表达式,它们将被更新。除了ng-click之外,还有其他一些内置指令/服务可以让你更改模型(例如ng-model,$ timeout等)并自动触发$ digest循环。
到目前为止,真好!但是,有一个小问题。在上面的例子中, Angular不会直接调用$ digest()。相反,它调用$ scope。$ apply(),后者又调用$ rootScope。$ digest()。因此,摘要周期从$ rootScope开始,随后访问所有调用观察者的子范围。"
然后更新rootscope变量,您会看到代码集中的更改。
答案 1 :(得分:0)
混淆源于您对$scope.$digest
下面的解释:
据我所知,当我们调用$ scope。$ digest()时,它不会更新父范围值
如果向该范围对象添加或修改属性,则父范围的值 将始终更新。任何JS对象都是如此(除非该对象被冻结或无法接收更新/新属性,但在这种情况下这一点并不重要)。
现在,该范围对象的新属性或修改属性是否反映在DOM中是另一回事。
在您的示例codepen中,您将通过在控制器中为其赋予新值来更新根范围:
$rootScope.value_on_root = "Value updated";
此更新反映在DOM中的原因是由于两件事:
您已在HTML中的控制器范围对象中隐式注册了value_on_root
的观察程序:
<div><strong>{{value_on_root}}</strong></div>
您的控制器范围正在使用原型继承,因此可以通过控制器的范围访问属性value_on_root
。 Understanding Scopes是一篇很好的文章,解释了AngularJS中的范围继承。来自文章:
如果我们尝试从子范围访问parentScope上定义的属性,JavaScript将首先查看子范围,而不是找到该属性,然后查看继承的范围,并找到该属性。 (如果它没有在parentScope中找到该属性,它将继续原型链......一直到根范围)。
在您的示例中,因为您当前范围内有value_on_root
观察者(由于上面的第1点),并且因为value_on_root
可通过您当前的范围访问(由于上面的第2点) ,$digest
完全按照预期行事:
它处理当前范围的所有观察者及其子女
如果我们在当前范围之外有value_on_root
观察者,或者您的控制器的范围有isolate scope,则$rootScope
上的属性更新不会反映在DOM。
我稍微修改了您的codepen in this example以证明我的观点。我通过向周围的HTML添加value_on_root
隐式地将{{value_on_root}}
观察者放在控制器范围之外。请注意,在此示例中,上传图像时不会更新外部value_on_root
。
如果您在my example中将$digest
更改为$apply
,则外部value_on_root
会更新。