在$手表触发角前pressions两次 [英] Angular expressions in $watch trigger twice

查看:103
本文介绍了在$手表触发角前pressions两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么这个 $观看火两次当一个简单的比较作为watchEx pression通过呢?

Why does this $watch fire twice when a simple comparison is passed as the watchExpression?

$scope.foo = 0;  // simple counter

$scope.$watch('foo > 4', function() {
  console.log("foo is greater than 4: ", $scope.foo);
});

监听火灾时,页面加载,当 0 ,然后一次(也是唯一一次)当的值超过4。

The listener fires when the page loads, when foo is 0, then once more (and only once more) when the value of foo goes above 4.

为什么听者火在页面加载时?而为什么没有继续开火时<$ ​​C $ C>富大于4?

Why does the listener fire when the page loads? And why doesn't it continue to fire when foo is greater than 4?

我成立了一个简单的plunkr显示发生的事情: http://plnkr.co/edit/ghYRl9 p = preVIEW

I set up a simple plunkr to show what's happening: http://plnkr.co/edit/ghYRl9?p=preview

推荐答案

重新阅读的角$手表文档几次,我想我明白发生了什么。

After re-reading the Angular $watch docs a few more times, I think I understand what's happening.

该监听器被调用时,只有从当前watchEx pression值和previous调用watchEx pression是不相等的。

The listener is called only when the value from the current watchExpression and the previous call to watchExpression are not equal

角跟踪watchEx pression 富&gt;中值; 4 每个消化()循环。由于此结果为假,直到是大于4,听者不火。同样,在大于4更大,角度值被比较都是真实的。在检测到变化的唯一时间是在评估前pression越过。

Angular tracks the value of the watchExpression foo > 4 with each digest() loop. Because this evaluated to false until foo was greater than 4, the listener didn't fire. Likewise, after foo was greater than 4, the values Angular was comparing were both true. The only time it detected a change was when the evaluated expression crossed over.

两个值传递给 $观看监听功能,新值和旧的。记录这些值表明watchEx pression正在评估和角度是寻找这些值的变化。

Two values are passed to the $watch listener function, the new value and the old one. Logging these values shows that the watchExpression is being evaluated, and Angular is looking for a change in those values.

$scope.$watch('foo > 4', function(newVal, oldVal) {
  console.log("foo is greater than 4: ", $scope.foo, oldVal, newVal);
});

// foo is greater than 4:  5 true false

监听器被称为在页面加载的原因还记载:

The reason the listener was called on page load is also documented:

在一个观察者与范围内注册,则监听器 FN异步调用(通过 $ evalAsync )以初始化守望。在极少数情况下,这是不可取的,因为当 watchEx pression 的结果并没有改变监听器被调用。为了检测侦听器内这种情况下 FN,你可以比较的newval OLDVAL 。如果这两个值是相同的( === ),那么监听器被称为因初始化。

After a watcher is registered with the scope, the listener fn is called asynchronously (via $evalAsync) to initialize the watcher. In rare cases, this is undesirable because the listener is called when the result of watchExpression didn't change. To detect this scenario within the listener fn, you can compare the newVal and oldVal. If these two values are identical (===) then the listener was called due to initialization.

我更新了 plunkr 与第二 $观看,其值富内部:

I updated the plunkr with a second $watch that evaluates the value of foo internally:

$scope.$watch('foo', function(newVal, oldVal) {
  if ($scope.foo > 4) {
  console.log("foo is greater than 4: ", $scope.foo, newVal, oldVal);
  }
});

// foo is greater than 4:  5 5 4
// foo is greater than 4:  6 6 5
// foo is greater than 4:  7 7 6

这篇关于在$手表触发角前pressions两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆