有 1 个 Angular 应用程序,带有 1 个父控制器和一个子控制器。 child中,OBJ-CHILD有1个$watch WATCH-CHILD,触发$emit。 在父级中,有一个 $emit 的监听器,我们将其称为 ON-LISTENER,以及一个用于 OBJ-PARENT 的 $watch WATCH-PARENT(它使用 true 作为第三个参数)。
当孩子的OBJ-CHILD改变时,会触发WATCH-CHILD,从而触发$emit。 父侦听器 ON-LISTENER 被触发,并更改 OBJ-PARENT。它还设置一些 $location 属性。 OBJ-PARENT 的 $watch WATCH-PARENT 永远不会被触发(即使值已经改变),并且在浏览器 URL 中 $location 上设置的属性也没有改变(我知道它们确实在 JavaScript 中改变了,因为我打印出来)。
为了确保在 $digest 中调用 ON-LISTENER,我尝试在 ON-LISTENER 末尾调用 $digest,并得到了预期的异常。
知道我是否做错了什么吗?我预计 ON-LISTENER 中发生的更改会触发 WATCH-PARENT 和浏览器 URL 更改。
如果成功,我将尝试在 jsfiddle 上重现并编辑这篇文章。
代码如下:
孩子:
$scope.$watch('vars.model', function(newValue, oldValue) {
console.log('model changed');
$scope.$emit('highlightChange', newValue);
}, true);
家长:
$scope.$watch('vars.model.highlight', function(newValue, oldValue) {
console.log('highlight changed');
}, true);
$scope.$on('highlightChange', function(event, value) {
console.log('listener', $scope.vars.model.highlight.categoryId, value.categoryId);
$location.search('category-id', value.categoryId);
$scope.vars.model.highlight.categoryId = value.categoryId;
}
下次请提供更多有效的代码,这样您才能得到更好的答案。
这是一个 Demo plunker,我创建它是为了测试您提供的代码。它工作得很好。如果您可以提供更多代码,那么我们就可以找到它不起作用的真正原因。
我创建了两个控制器parentCtrl和childCtrl,它们使用您的代码和提供的结构的对象。
$scope.vars = {
model:{
highlight:{
categoryId : 5 //This value is set for testing purposes
}
}
};
此外,我将监视目标(vars.model -> vars.model.highlight)更改为与父控制器中的相同
$scope.$watch('vars.model.highlight', function(newValue, oldValue) {
console.log('child model changed (new/old)', newValue, oldValue);
$scope.$emit('highlightChange', newValue);
console.log('Emited change event');
}, true);
我发现我的事件源自对 $scope.$digest() 的手动调用,因为原始事件是由 daterangepicker 'apply.daterangepicker' 事件触发的。 当我将其更改为 $scope.$apply 时,问题似乎就消失了。 我可以由此假设,只要有变化, $apply() 就是负责不断调用 $watch 的人,而 $digest() 则不会这样做。
为了以后参考,我把问题放在这里: https://plnkr.co/edit/ItkALhw16Aqukk3EFrRz?p=preview
$scope.digest();
应该成为
$scope.apply();