我有一个函数循环遍历列表,如果是项目,然后对每个项目进行ajax调用外部api。
这一切都可以在循环中单独调用它。但我想要做的是让用户可以随时取消请求。当列表很小(大约<20)时,该过程在大约2-3秒内完成,这很好。但有时列表可能是几百个,可能需要几分钟才能运行,我想让用户可以随时取消此选项。
这就是我现在所拥有的:
<button type="button" class="btn btn-default" ng-click="getData(myList)">Get All Data</button>
<button type="button" class="btn btn-default" ng-click="cancelProcessCalls()">Get All Data</button>
<div ng-repeat="item in myList">
<div>
<div>{{item.Id}}</div>
<div>{{item.Name}}</div>
<div>
<span ng-bind-html="item.statusText"></span>
<span ng-bind="item.Data"></span>
</div>
</div>
</div>
angular / jquery代码是:
$scope.getData = function (itemList) {
if (itemList != null) {
$.each(itemList, function (index, item) {
$scope.getItemData(item);
});
}
};
$scope.cancelProcessCalls = function () {
$scope.processCalls=false;
};
$scope.getItemData = function (item) {
if ($scope.processCalls) {
if (item != null) {
item.statusText = "Getting data...";
$.ajax({
url: _url + item.Id,
method: 'GET'
})
.fail(function (data, textStatus, jqXHR) {
$scope.handleError(data, textStatus, jqXHR);
})
.done(function (data) {
item.Data = data;
})
.then(function (data, textStatus, jqXHR) {
})
.always(function (data, textStatus, jqXHR) {
item.statusText = null;
$scope.$apply();
});
}
}
};
所以第一个函数只是循环遍历列表并为每个项目调用。
我尝试添加一个变量来检查是否继续调用,但这样做并不起作用,因为它全部包含在工作范围内。
是否有一种简单的方法可以优雅地取消或突破该循环?
答案 0 :(得分:1)
这样的事情应该有效。这个想法是你将xhr对象存储在一个数组中,然后当你想要取消时,你循环数组并在请求上调用abort。
$scope.requests = [];
$scope.getData = function(itemList) {
$scope.cancelProcessCalls();
if (itemList != null) {
$.each(itemList, function(index, item) {
$scope.getItemData(item);
});
}
};
$scope.cancelProcessCalls = function() {
for (var i = 0; i < $scope.requests.length; i++) {
$scope.requests[i].abort();
}
$scope.requests.length = 0;
};
$scope.getItemData = function(item) {
if ($scope.processCalls) {
if (item != null) {
item.statusText = "Getting data...";
var xhr = $.ajax({
url: _url + item.Id,
method: 'GET'
});
$scope.requests.push(xhr);
xhr.fail(function(data, textStatus, jqXHR) {
$scope.handleError(data, textStatus, jqXHR);
})
.done(function(data) {
item.Data = data;
})
.then(function(data, textStatus, jqXHR) {})
.always(function(data, textStatus, jqXHR) {
item.statusText = null;
$scope.$apply();
}););
}
}
答案 1 :(得分:0)
$scope.breakCheck = false;
$scope.getData = function (itemList) {
if (itemList != null) {
$.each(itemList, function (index, item) {
if ($scope.breakCheck) {
return;
}
$scope.getItemData(item, $scope);
});
}
};
$scope.cancelProcessCalls = function () {
$scope.processCalls=false;
};
$scope.getItemData = function (item, scope) {
scope.breakCheck = true; // You can move this line anywhere to decide when you want to stop the ajax
if ($scope.processCalls) {
if (item != null) {
item.statusText = "Getting data...";
$.ajax({
url: _url + item.Id,
method: 'GET'
})
.fail(function (data, textStatus, jqXHR) {
$scope.handleError(data, textStatus, jqXHR);
})
.done(function (data) {
item.Data = data;
})
.then(function (data, textStatus, jqXHR) {
})
.always(function (data, textStatus, jqXHR) {
item.statusText = null;
$scope.$apply();
});
}
}
};