要了解正在发生的事情,您需要了解 Angular 的$digest https://docs.angularjs.org/api/ng/type/%24rootScope.Scope#%24digest周期和事件$emit 和 $broadcast https://docs.angularjs.org/api/ng/type/%24rootScope.Scope#%24emit功能。
根据一些研究,我还了解到 Angular。 Angular 文档中没有对此进行解释,但可以进行测试(请参阅这个类似问题的答案 https://stackoverflow.com/questions/23460025/when-digest-cycle-is-called#answer-23460476).
把所有这些放在一起,我写了一个简单的实验 https://jsfiddle.net/a0d0ud2o/2/并得出结论,您可以首先运行事件处理程序,然后再运行手表功能。这是有道理的,因为在摘要循环期间可以连续调用监视函数多次。
下面的代码...
模板.html
<div ng-app="myApp">
<div watch-foo ng-controller="FooController">
<button ng-click="changeFoo()">
Change
</button>
</div>
</div>
脚本.js
angular.module('myApp', [])
.directive('watchFoo', watchFooDirective)
.controller('FooController', FooController);
function watchFooDirective($rootScope) {
return function postLink(scope) {
scope.$watch(function () {
return scope.foo;
}, function (value) {
console.log('scope.$watch A');
});
scope.$on('foo', function (value) {
console.log('scope.$on A');
});
$rootScope.$on('foo', function (value) {
console.log('$rootScope.$on A');
});
$rootScope.$on('foo', function (value) {
console.log('$rootScope.$on B');
});
scope.$on('foo', function (value) {
console.log('scope.$on B');
});
scope.$watch(function () {
return scope.foo;
}, function (value) {
console.log('scope.$watch B');
});
};
}
function FooController($scope) {
$scope.foo = 'foo';
$scope.changeFoo = function() {
$scope.foo = 'bar';
$scope.$emit('foo');
};
}
...单击“更改”按钮时,控制台中会产生以下结果:
scope.$on A
scope.$on B
$rootScope.$on A
$rootScope.$on B
scope.$watch A
scope.$watch B
UPDATE
这是另一个测试,说明了监视回调在摘要循环中被调用两次,但事件处理程序没有被第二次调用:https://jsfiddle.net/sscovil/ucb17tLa/ https://jsfiddle.net/sscovil/ucb17tLa/
第三个测试在 watch 函数内发出一个事件,然后更新正在监视的值:https://jsfiddle.net/sscovil/sx01zv3v/ https://jsfiddle.net/sscovil/sx01zv3v/
在所有情况下,您都可以依赖在监视函数之前调用的事件侦听器。