所有
我得到一个关于angularjs数据摘要如何监视范围数据更改的问题,例如:
<button ng-click="changename()">{{name}}</button>
数据更改功能如下:
$scope.name = "Change Name";
$scope.changename = function(){
$scope.name = "name1";
$scope.name = "name2";
}
$scope.$watch("name", function(newname, oldname){
if(newname!=oldname){
console.log("new: "+newname, "old: "+oldname);
}
});
此changename函数连续两次更改scope.name,但观察者可以仅捕获更改名称&#34;更改名称&#34; to&#34; name2&#34; (控制台只打印&#34;新:name2 old:更改名称&#34;)
任何人确认我的猜测,摘要周期只能在功能块执行完毕后才开始吗?
由于
答案 0 :(得分:2)
我想更正来自rbaghbanli
的误导性答案。
的确,因为JavaScript是单线程的,所以点击该按钮时会发生以下情况:
The variable `$scope.name` is set to "name1";
The variable `$scope.name` is set to "name2";
> end of execution stack
Angular runs a $digest cycle
The $watchers are executed
since a watcher value has changed, angular runs another $digest cycle
The $watchers are executed
The watcher have the same value, end of $digest cycle
> end of execution stack
因此,当你在同一个函数内时,基本上没有观察者也不会发生任何事情,直到这个函数的每一行结束。
Angular在changename
调用之后运行摘要周期的原因是因为它在ng-click
指令内,并且与所有Angular内置指令一样,代码实际上包含在{ {1}}致电。您可以阅读$scope.$apply
作为以下代码(即使从技术上讲它不完全是这样的):
ng-click
注意:我想简化通用的想法,但从技术上来说,Angular在你的代码之后执行它的$ digest循环(正如你在我的伪element.on('click', function() {
$scope.changename();
$rootScope.$digest();
});
中看到的那样),在同一个执行堆栈。这意味着在摘要周期之后以及使用最新更改更新DOM之后将发生任何ng-click
或其他异步调用,这有时非常有用。
答案 1 :(得分:0)
是和否。 JavaScript是在单个线程上执行的,所以$ watch函数会有2个调用,但只有在$scope.changename()
完成后才会调用,所以第二个调用将有newname == oldname == 'name2'
。
答案 2 :(得分:0)
通常,Angular会在发生某些事件后触发摘要周期。在您的情况下,ngClick
指令在执行提供的表达式后触发摘要。对于许多其他用户触发的事件也是如此,例如mouseover
,keydown
,keypress
。
因此,在name
内更改changename()
的次数并不重要;下一个摘要周期只会“看到”指定的最后一个值。