joe*_*ler 14 javascript angularjs
$watch
当一个简单的比较作为watchExpression传递时,为什么会激发两次?
$scope.foo = 0; // simple counter
$scope.$watch('foo > 4', function() {
console.log("foo is greater than 4: ", $scope.foo);
});
Run Code Online (Sandbox Code Playgroud)
当页面加载时,当收听者的火灾foo
是0
,则一次(且仅一次)时的值foo
变得高于4.
为什么在页面加载时监听器会触发?当foo
大于4 时为什么不继续发射?
我设置了一个简单的plunkr来显示正在发生的事情:http://plnkr.co/edit/ghYRl9?p = preview
joe*_*ler 23
在重新阅读Angular $ watch文档几次之后,我想我明白了发生了什么.
仅当当前watchExpression的值和之前对watchExpression的调用不相等时才会调用侦听器
Angular跟踪foo > 4
每个digest()
循环的watchExpression的值.因为这被评估为假,直到foo
大于4,所以听众没有开火.同样,在foo
大于4之后,Angular比较的值都是正确的.它检测到变化的唯一时间是评估的表达式越过.
将两个值传递给$watch
侦听器函数,新值和旧值.记录这些值表明正在评估watchExpression,Angular正在寻找这些值的更改.
$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
Run Code Online (Sandbox Code Playgroud)
还记录了在页面加载时调用侦听器的原因:
在观察者注册观察者之后,
listener
异步调用fn(通过$evalAsync
)来初始化观察者.在极少数情况下,这是不合需要的,因为当结果watchExpression
没有改变时调用监听器.要在listener
fn中检测这种情况,您可以比较newVal
和oldVal
.如果这两个值相同(===
)则由于初始化而调用了侦听器.
我用第二个更新了plunkr$watch
来评估foo
内部的值:
$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
Run Code Online (Sandbox Code Playgroud)