250605-AngularJS-Button防止重复点击解决办法

范式

1
2
3
4
5
6
7
8
9
10
11
12
13
let isProcessing = false;


if (isProcessing) {
return false; // 防止重复点击
}
isProcessing = true;


// 模拟异步操作完成后恢复按钮状态
setTimeout(function() {
isProcessing = false;
}, 2000);

方案一

angularjs 能不能实现一个组件,放到所有的按钮上面,控制ng-click防重复提交策略

在 AngularJS 中,可以通过创建一个自定义指令来实现一个通用的防重复点击组件,这个指令可以附加到任何按钮上,以控制 ng-click
的防重复提交策略。

以下是一个完整的示例:

1. 创建防重复点击指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 增加按钮防重复点击组件
app.directive('preventRepeatedClick', function ($parse, $timeout) {
return {
restrict: 'A',
priority: 1000, // 确保指令在ngClick之后执行
scope: {
clickDelay: '@'
},
link: function (scope, element, attrs) {
var isProcessing = false;

var delay = parseInt(attrs.clickDelay) || 2000; // 默认延迟 2000 毫秒
delay = (delay >= 2000) ? delay : 2000;

element.on('click', function (event) {
// 如果正在处理事件,直接返回,防止重复点击
if (isProcessing) {
event.preventDefault();
event.stopPropagation();
return;
}

// 禁用按钮,防止重复点击
isProcessing = true;
element.attr('disabled', 'disabled');

// 延迟后启用按钮
$timeout(function () {
isProcessing = false;
element.removeAttr('disabled');
}, delay);
});
}
};
});

2. 使用自定义指令

在 HTML 中,将 prevent-repeated-click 指令附加到按钮上,并可选地指定 click-delay 属性来设置按钮禁用的时间(以毫秒为单位)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS 防重复点击指令</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="myCtrl">
<button prevent-repeated-click click-delay="2000" ng-click="buttonClick()">点击我</button>
<p>{{message}}</p>
</div>
</body>
</html>

3. 控制器逻辑

在控制器中定义按钮的点击处理函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
app.controller('myCtrl', function ($scope) {
$scope.message = '';

$scope.buttonClick = function () {
console.log('按钮被点击了');
$scope.message = '按钮被点击,正在处理...';
// 模拟处理逻辑
setTimeout(function () {
$scope.message = '处理完成';
$scope.$apply(); // 触发 AngularJS 的 digest 循环
}, 2000);
};
});

解释

  1. **自定义指令 preventRepeatedClick**:
    • **restrict: 'A'**:指定该指令为属性类型。
    • **scope**:定义指令的隔离作用域,ngClick 用于绑定按钮的点击事件,clickDelay 用于设置按钮禁用的时间。
    • link 函数:在指令的链接函数中,监听按钮的点击事件。
      • **isProcessing**:标记按钮是否正在处理事件。
      • **delay**:从 click-delay 属性获取按钮禁用的时间,如果没有指定则使用默认值 2000 毫秒。
      • 禁用按钮:在点击事件发生时,如果 isProcessingtrue,阻止事件的默认行为并返回,防止重复点击。否则,将
        isProcessing 设置为 true 并禁用按钮。
      • **触发 ng-click**:调用绑定的 ngClick 函数。
      • 延迟启用按钮:使用 $timeout 在指定的延迟时间后将 isProcessing 设置为 false 并启用按钮。
  2. 使用指令
    • 在按钮上添加 prevent-repeated-click 指令,并可选地使用 click-delay 属性来指定按钮禁用的时间。
    • 绑定 ng-click 到按钮的点击处理函数。
  3. 控制器逻辑
    • 定义按钮的点击处理函数 buttonClick,在其中执行相关的业务逻辑。

通过这种方式,你可以将 prevent-repeated-click 指令附加到任何按钮上,以实现防重复点击的功能,而无需在每个按钮的控制器中重复编写相同的逻辑。

方案二

AngularJS 的双向数据绑定来实现。以下是一个示例:

  1. HTML 部分:使用 ng-disabled 指令来绑定按钮的禁用状态。
  2. JavaScript 部分:在控制器中定义一个变量来控制按钮的禁用状态,并在事件处理函数中修改这个变量。

HTML

1
2
3
4
5
<div ng-app="myApp">
<div ng-controller="myCtrl">
<button ng-click="buttonClick($event)" ng-disabled="isDisabled">点击我</button>
</div>
</div>

JavaScript

1
2
3
4
5
6
7
8
9
10
11
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
// 初始化按钮禁用状态为 false
$scope.isDisabled = false;

$scope.buttonClick = function($event) {
console.log('按钮被点击了');
// 修改按钮的禁用状态
$scope.isDisabled = !$scope.isDisabled;
};
});

在这个示例中,我们使用了 ng-disabled 指令来绑定按钮的禁用状态到 $scope.isDisabled 变量。当点击按钮时,buttonClick
函数会被调用,它会切换 $scope.isDisabled 的值,从而改变按钮的禁用状态。

  • 初始状态下,$scope.isDisabledfalse,按钮是启用状态。
  • 当按钮被点击时,buttonClick 函数将 $scope.isDisabled 设置为 true,按钮变为禁用状态。
  • 再次点击按钮时,buttonClick 函数将 $scope.isDisabled 设置为 false,按钮恢复启用状态。