AngularJS 中什么时候触发摘要
When does the digest get triggered in AngularJS
全部:
我有一个关于 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两次,但是观察者只能捕捉到从"Change Name"到"name2"的变化(控制台只打印 "new: name2 old: Change Name")
谁能证实我的猜测摘要循环仅在功能块执行完毕后才开始?
谢谢
是也不是。 JavaScript 是在单线程上执行的,所以会有 2 次调用 $watch 函数,但是只有在 $scope.changename()
完成之后,所以第二次调用会有 newname == oldname == 'name2'
.
通常 Angular 在 某些事件发生后 触发摘要循环。在您的情况下, ngClick
指令在执行提供的表达式后触发摘要。对于许多其他用户触发的事件也是如此,例如mouseover
, keydown
, keypress
.
所以在changename()
里面改变name
多少次都没有关系;下一个摘要周期只会 "see" 最后分配的值。
我想更正 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 内置一样指令,代码实际上包含在 $scope.$apply
调用中。您可以将 ng-click
解读为以下代码(即使从技术上讲它并不完全像这样):
element.on('click', function() {
$scope.changename();
$rootScope.$digest();
});
注意:我想简化通用的想法,但从技术上讲,Angular 会在您的代码之后立即执行其 $digest 循环(正如您在我的伪 ng-click
中看到的那样), 在同一个执行堆栈中。这意味着任何 setTimeout
或其他异步调用都将在 之后 摘要周期和 DOM 更新为最新更改后发生,这有时很有用。
全部:
我有一个关于 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两次,但是观察者只能捕捉到从"Change Name"到"name2"的变化(控制台只打印 "new: name2 old: Change Name")
谁能证实我的猜测摘要循环仅在功能块执行完毕后才开始?
谢谢
是也不是。 JavaScript 是在单线程上执行的,所以会有 2 次调用 $watch 函数,但是只有在 $scope.changename()
完成之后,所以第二次调用会有 newname == oldname == 'name2'
.
通常 Angular 在 某些事件发生后 触发摘要循环。在您的情况下, ngClick
指令在执行提供的表达式后触发摘要。对于许多其他用户触发的事件也是如此,例如mouseover
, keydown
, keypress
.
所以在changename()
里面改变name
多少次都没有关系;下一个摘要周期只会 "see" 最后分配的值。
我想更正 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 内置一样指令,代码实际上包含在 $scope.$apply
调用中。您可以将 ng-click
解读为以下代码(即使从技术上讲它并不完全像这样):
element.on('click', function() {
$scope.changename();
$rootScope.$digest();
});
注意:我想简化通用的想法,但从技术上讲,Angular 会在您的代码之后立即执行其 $digest 循环(正如您在我的伪 ng-click
中看到的那样), 在同一个执行堆栈中。这意味着任何 setTimeout
或其他异步调用都将在 之后 摘要周期和 DOM 更新为最新更改后发生,这有时很有用。