Angular不会识别forEach循环中的作用域变量变化

Angular does not recognize scope variable change within forEach loop

本文关键字:作用域 变量 变化 循环 识别 forEach Angular      更新时间:2023-09-26

我有一个包含一些测试的数组,我必须依次运行这些测试。
在一个角forEach循环中,我迭代测试数组并通过http get调用后端来启动当前测试。
我现在的问题是,用户应该有可能停止测试运行,以便不再执行进一步的测试。在视图中,我有一个"停止测试运行"按钮,它设置了一个$scope。stopTest变量设置为true。在我的foreach循环中,我有一个检查$作用域的条件。stopTest变量,如果设置为true,则跳过测试运行。
但似乎,在循环内部,angular无法识别作用域变量从false变为true。我在循环中有一个测试输出,它告诉我值仍然为false。

在我的视图中,我有这些按钮:

<input type="button" class="btn" ng-click="runTests()" value="Start test run" ng-disabled="disabled == true" />
<input type="button" class="btn" ng-click="stopRunning = true" value="Stop test run" />

在我的控制器中,我有这样的代码:

$scope.runTests = function () {
angular.forEach($scope.selected, function (value, key) {
    if (!$scope.stopRunning) { // PROBLEM: angular does not recognize that stopRunning has changed already
        promise = promise.then(function () {
            $scope.count++;
            $scope.status = "Running test " + $scope.count + " of " + $scope.countSelectedTests + ".";
            return $http({
                method: 'GET',
                url: 'api/runtest/' + key
            }).then(function (res) {                            
                   $scope.testresults = res.data;                               
            });
        });   
    }
});

有谁知道这里有什么问题吗?是关于子作用域还是消化周期?我试图在改变stopRunning变量后调用$apply()或$digest(),但没有效果。

如何通过按钮点击事件停止循环?

我很确定问题*来自angular的forEach。你们见过这个问题吗?

*函数本身没有问题,只是不应该这样使用。

好吧,不用了。我认为问题在于你的循环发生得太快了。它循环遍历所有"选定"元素,并在您甚至可以单击停止按钮之前启动所有查询。如果您想要链式调用,请编写一个递归函数来执行调用,并在返回时为下一个元素调用自身。这样,每个http调用都将在前一个调用完成后启动,您将有时间中断该进程。

 function callForEach(selected, i){
     if(i < selected.length){
     var item = selected(i);
     $http({
            method: 'GET',
            url: 'api/runtest/' + key
        }).then(function (res) {                            
               $scope.testresults = res.data;
            if(!$scope.stopRunning){
              callForEach(selected, i+1);
            }                               
        });
     }
 }