我正在寻找一种基于AngularJS的方法来防止每个任务多次提交。
我不需要在提交或关闭表单后禁用按钮并等待任务完成。相反,我需要独特的请求。
为了更详细,我需要$http.get
和$http.post
停止发送多个相同的请求。
任何想法?
答案 0 :(得分:4)
根据这篇文章,您可以使用提供者装饰者
注意:此方法基于angular-api
https://gist.github.com/adambuczynski/354364e2a58786e2be71
<强>更新强>
我在您建议的解决方案中更改了一小部分,因为返回的承诺已丢失.success
以及.error
和.then
。
只需使用此编辑的代码即可使所有这些功能正常工作:
.config(["$provide", function ($provide) {
$provide.decorator('$http', function ($delegate, $q) {
var pendingRequests = {};
var $http = $delegate;
function hash(str) {
var h = 0;
var strlen = str.length;
if (strlen === 0) {
return h;
}
for (var i = 0, n; i < strlen; ++i) {
n = str.charCodeAt(i);
h = ((h << 5) - h) + n;
h = h & h;
}
return h >>> 0;
}
function getRequestIdentifier(config) {
var str = config.method + config.url;
if (config.data && typeof config.data === 'object') {
str += angular.toJson(config.data);
}
return hash(str);
}
var $duplicateRequestsFilter = function (config) {
if (config.ignoreDuplicateRequest) {
return $http(config);
}
var identifier = getRequestIdentifier(config);
if (pendingRequests[identifier]) {
if (config.rejectDuplicateRequest) {
return $q.reject({
data: '',
headers: {},
status: config.rejectDuplicateStatusCode || 400,
config: config
});
}
return pendingRequests[identifier];
}
pendingRequests[identifier] = $http(config);
$http(config).finally(function () {
delete pendingRequests[identifier];
});
return pendingRequests[identifier];
};
Object.keys($http).filter(function (key) {
return (typeof $http[key] === 'function');
}).forEach(function (key) {
$duplicateRequestsFilter[key] = $http[key];
});
return $duplicateRequestsFilter;
})
}])
答案 1 :(得分:0)
这可能是一个性能问题,但遵循这个想法可以解决您的问题。
将每个请求URL和DATA存储为变量的键值对。网址应为KEY。对于相同的URL,多次提交可以存储在数组中。
然后对于任何新的调用,检查URL是否存在于您的存储对象中,然后彻底地将数据与每个对象进行比较(深层检查,但是它很昂贵)。 如果发现任何完全匹配,则停止处理。同样的要求来了。 其他明智的做法,也不要忘记存储这些数据。
但由于需要检查可能很糟糕的数据,因此成本很高。
注意:在存储数据时,您可以将其转换为JSON字符串,以便在String之间进行比较。
这是Code Algo
YourService.call(url, params) {
var Str1 = JSON.stringify(params);
if(StoredObj[url]) {
for each (StoredObj[url] as Str){
if(Str === Str1) {
return;
}
}
}
else {
StoredObj[url] = []; //new Array
}
StoredObj[url].push(Str1);
Call $http then;
}