javascript - AngularJS $watch - 无限循环

标签 javascript angularjs watch digest

我有 2 个日期 - 开始和结束。我想验证(并重新确保)开始 < 结束。 我收到通知,他们使用 $watch 进行了更改,然后我去更改它们以确保满足条件,但随后它再次触发 $watch,然后我获得了 $digest 的最大迭代次数,然后事情就开始了。

所以我的问题是 - 如何更改在 $watch 中监视的变量而不导致无限循环。 (除了进行更多检查并仅在实际需要更改时更改它们)

这是我的代码:

var TIME_DAY = 1000 * 60 * 60 * 24;

$scope.$watch('timeFilter.startTime', function () {
    validateStartEndTime();
},true);

$scope.$watch('timeFilter.endTime', function () {
    validateStartEndTime();
},true);

function validateStartEndTime() {
    if ($scope.timeFilter.startTime != null && $scope.timeFilter.endTime != null) {
        // Remove all seconds
        if ($scope.timeFilter.startTime.getSeconds() > 0)
            $scope.timeFilter.startTime.setSeconds(0);
        if ($scope.timeFilter.endTime.getSeconds() > 0)
            $scope.timeFilter.endTime.setSeconds(0);
        if ($scope.timeRange.minTime.getSeconds() > 0)
            $scope.timeRange.minTime.setSeconds(0);
        if ($scope.timeRange.maxTime.getSeconds() > 0)
            $scope.timeRange.maxTime.setSeconds(0);

        // When start time isn't before end time
        if ($scope.timeFilter.startTime >= $scope.timeFilter.endTime) {
            // We want to increase end time by 1 minute, if possible - do it. Else - reduce start time by 1 minute
            if ($scope.timeFilter.endTime < $scope.timeRange.maxTime) {
                $scope.timeFilter.endTime.setMinutes($scope.timeFilter.startTime.getMinutes() + 1);
            } else {
                $scope.timeFilter.startTime.setMinutes($scope.timeFilter.startTime.getMinutes() - 1);
            }
        }

        // Start time before min time
        if ($scope.timeFilter.startTime < $scope.timeRange.minTime) {
            $scope.timeFilter.startTime = $scope.timeRange.minTime;
            if ($scope.timeFilter.endTime <= $scope.timeFilter.startTime) {
                $scope.timeFilter.endTime = $scope.timeFilter.startTime;
                $scope.timeFilter.endTime.setMinutes($scope.timeFilter.endTime.getMinutes() + 1);
            }
        }

        // End time after max time
        if ($scope.timeFilter.endTime > $scope.timeRange.maxTime) {
            $scope.timeFilter.endTime = $scope.timeRange.maxTime;
            if ($scope.timeFilter.startTime >= $scope.timeFilter.endTime) {
                $scope.timeFilter.startTime = $scope.timeFilter.endTime;
                $scope.timeFilter.startTime.setMinutes($scope.timeFilter.startTime.getMinutes() - 1);
            }
        }
    }
}

最佳答案

老实说,我更愿意找到一种方法来避免更改不断监视的变量。但是,如果您真的想要,您可以在必须更改正在监视的变量时注销 $watch 函数,然后重新注册 $watch 函数。

要注销 $watch 函数,您只需获取引用并在需要时调用即可。

var myWatch = $scope.$watch('timeFilter.startTime', function () {
   validateStartEndTime();
},true);
myWatch(); // It will deregister it.

请记住,有时当您第一次观察一个变量时,它会自动触发该函数。我的建议是始终检查旧变量是否真的改变了。

var myWatch = $scope.$watch('timeFilter.startTime', function (newValue, oldValue) {
   if(newValue === oldValue){
      return;
   }
   validateStartEndTime();
},true);

希望对你有用。很遗憾,我现在无法测试此代码。

关于javascript - AngularJS $watch - 无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32369567/

相关文章:

javascript - 通过 Angular 指令上传图像并在 DOM 上显示

javascript - 如何在javascript中按两个名称对数组进行排序?

javascript - 在 Canvas 上交换图像会占用内存

javascript - 如何将提交的表单数据发送到本地服务器

javascript - 到 HTML 文件的 Angular 路由不起作用

javascript - jQuery:观察节点值的变化

javascript - Node.js 中的 SocketCAN

angularJS - 在表中重复 tr,但在循环时动态添加更多行

javascript - 使用 Angular 7 在混合应用程序中加载 Angularjs 包

powershell - 使用 PowerShell 的类型 -wait 和 select-string 实时监控应用程序日志的条件并执行操作(如 tail -f 或 watch)