我有一个包含一些测试的数组,我必须按顺序运行。
在一个有角度的forEach循环中,我迭代测试数组并通过http调用后端来启动当前测试。
我的问题是,用户应该有可能停止测试运行,以便不再执行进一步的测试。
在视图中,我有一个“停止测试运行”按钮,它将$ scope.stopTest变量设置为true。在我的foreach循环中,我有一个条件,它在每次迭代时检查$ scope.stopTest变量,如果设置为true则跳过测试运行。
但看起来,在循环内部角度不能识别范围变量从false变为true。
我在循环中有一个测试输出,告诉我该值仍然是假的。
在我看来,我有这些按钮:
<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(),但没有效果。
如何通过按钮点击事件停止循环?
答案 0 :(得分:1)
我很确定问题*来自angular的forEach。你见过this other question吗?
*函数本身不是问题,它不应该以这种方式使用。
好的,废弃了。 我认为问题是你的循环发生得太快了。它遍历所有“选定”元素,并在您甚至可以单击停止按钮之前启动所有查询。如果你想链接调用,写一个执行调用的递归函数,并在返回时调用自己的下一个元素。 这样,每个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);
}
});
}
}