在angular中我们可以设置一个按钮来发送像这样的ajax请求:
... ng-click="button-click"
Run Code Online (Sandbox Code Playgroud)
在控制器中:
...
$scope.buttonClicked = function() {
...
...
// make ajax request
...
...
}
Run Code Online (Sandbox Code Playgroud)
因此,为了防止双重提交,我可以在单击按钮时将buttonclicked设置为true,并在ajax回调完成时取消设置.但是,即使这样,控制也会被处理回角色,他们会更新Dom.这意味着在原始按钮单击完全100%完成之前,有一个小窗口可以再次单击按钮.
这是一个小窗口,但仍然可以发生.任何提示,以完全避免这种情况发生 - 客户端即没有对服务器进行任何更新.
谢谢
zs2*_*020 40
首先你最好添加ngDblclick,当它检测到双击时返回false
:
<ANY ng-click="buttonClicked()" ng-dblclick="return false">
Run Code Online (Sandbox Code Playgroud)
如果要等待Ajax调用完成,则可以通过设置ng-disabled来禁用该按钮
<ANY ng-click="buttonClicked()" ng-dblclick="return false;" ng-disabled="flag">
Run Code Online (Sandbox Code Playgroud)
在你的控制器中,你可以做到
$scope.flag = false;
$scope.buttonClicked = function() {
$scope.flag = true;
Service.doService.then(function(){
//this is the callback for success
$scope.flag = false;
}).error(function(){
//this is the callback for the error
$scope.flag = false;
})
}
Run Code Online (Sandbox Code Playgroud)
当ajax调用成功或失败时,您需要处理这两种情况,因为如果它失败了,您不希望它显示为禁用混淆用户.
Jon*_*mbo 35
ng-disabled
在这个例子中使用工作正常.无论我多么疯狂地点击控制台消息只填充一次.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.submitData = function() {
$scope.buttonDisabled = true;
console.log("button clicked");
}
function augment() {
var name, fn;
for (name in $scope) {
fn = $scope[name];
if (typeof fn === 'function') {
if (name.indexOf("$") !== -1) {
$scope[name] = (function(name, fn) {
var args = arguments;
return function() {
console.log("calling " + name);
console.time(name);
fn.apply(this, arguments);
console.timeEnd(name);
}
})(name, fn);
}
}
}
}
augment();
});
Run Code Online (Sandbox Code Playgroud)
<!doctype html>
<html ng-app="plunker">
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<input type="button" ng-click="submitData()" ng-disabled="buttonDisabled" value="Submit" />
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我很好奇角度将更改应用到buttonDisabled
标志需要多长时间.如果在plunker 示例中检查控制台,则会显示执行$eval
和$apply
执行方法所需的时间.在我的机器上,它平均需要1-2毫秒.
小智 11
我只是扩展了zsong的代码,在标志的处理程序中添加一个检查.如果它是真的那么只返回因为已经处理了一个点击.这可以防止双击而不用担心角度定时或类似的事情.
$scope.flag = false;
$scope.buttonClicked = function() {
if ($scope.flag) {
return;
}
$scope.flag = true;
Service.doService.then(function(){
//this is the callback for success
$scope.flag = false;
}).error(function(){
//this is the callback for the error
$scope.flag = false;
})
}
Run Code Online (Sandbox Code Playgroud)
您可以使用我刚刚完成的指令来防止用户在执行异步操作时多次单击元素
https://github.com/mattiascaricato/angular-click-and-wait
您可以使用npm或bower将其添加到项目中
npm install angular-click-and-wait
Run Code Online (Sandbox Code Playgroud)
要么
bower install angular-click-and-wait
Run Code Online (Sandbox Code Playgroud)
const myApp = angular.module('myApp', ['clickAndWait']);
myApp.controller('myCtrl', ($scope, $timeout) => {
$scope.asyncAction = () => {
// The following code simulates an async action
return $timeout(() => angular.noop, 3000);
}
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://cdn.rawgit.com/mattiascaricato/angular-click-and-wait/master/dist/click-and-wait.js"></script>
<section ng-app="myApp">
<div ng-controller="myCtrl">
<button click-and-wait="asyncAction()">Click Me!</button>
</div>
</section>
Run Code Online (Sandbox Code Playgroud)
注意:作为参数传递的异步操作应该是Promise