Angular中按Enter键提交后如何禁用提交按钮防止重复提交

问题描述
扫描信标设备时,扫描器会在发送完信标ID后自动追加一个Enter回车信号。实际使用中存在用户扫描信标触发Enter提交后,又手动点击提交按钮的场景,会导致onSubmit()方法被多次重复调用。
约束规则:必须保留Enter键的提交触发能力,和应用内其他UI交互逻辑保持一致,禁止将按钮
type属性从submit改为button,也不允许直接屏蔽Enter键默认事件。
现有实现代码
<form [formGroup]="commissioningForm" class=commission-form #formGroupDirective> <mat-form-field appearance="standard"> <mat-label>Beacon Id</mat-label> <input #beaconIdEle matInput placeholder="Scan or type..." formControlName="beaconId" autocomplete="off" specialCharacterRegex/> <mat-error *ngIf="beaconId.invalid">Not a valid Beacon Id.</mat-error> </mat-form-field> <br /> <br /> <button type="submit" (click)="onSubmit()" [disabled]="commissioningForm.invalid" mat-raised-button> Submit </button> </form>
已尝试的无效方案
之前尝试通过processingSubmit标志位做防重,但因为没有等待异步方法执行完成就立刻重置标志位,方案完全不生效,代码如下:
onSubmit() { if( !this.processingSubmit ) { this.processingSubmit = true; this.async_method_call(); // 异步调用未等待完成就重置状态,标志位无法拦截重复请求 this.processingSubmit = false; return true; } else { return false; } }
可行解决方案
核心逻辑是提交触发后立刻禁用按钮,等整个异步提交流程结束后再恢复按钮可用,完全不改动原有Enter键提交逻辑,符合约束要求:
- 第一步:修改提交按钮的禁用绑定规则,把提交中状态加入禁用判断条件,不需要修改按钮的
type="submit"属性:
<button type="submit" (click)="onSubmit()" [disabled]="commissioningForm.invalid || processingSubmit" mat-raised-button> Submit </button>
- 第二步:修正
onSubmit方法的状态重置逻辑,必须等异步方法执行完成(包含成功、失败两种场景)后,再把processingSubmit重置为false。- 如果异步方法返回Promise,写法如下:
async onSubmit() { if (this.processingSubmit) return; this.processingSubmit = true; try { await this.async_method_call(); // 提交成功后的业务逻辑,如表单重置、结果提示等 } catch (err) { // 提交失败的错误处理 } finally { // 无论成功失败,异步流程结束后再恢复按钮可点击状态 this.processingSubmit = false; } }- 如果异步方法返回RxJS Observable(Angular HttpClient默认返回该类型),写法如下:
import { finalize } from 'rxjs/operators'; onSubmit() { if (this.processingSubmit) return; this.processingSubmit = true; this.async_method_call() .pipe(finalize(() => { // 成功、报错场景都会触发该逻辑,保证状态一定会被重置 this.processingSubmit = false; })) .subscribe({ next: (res) => { // 提交成功业务逻辑 }, error: (err) => { // 提交失败错误处理 } }) }
当扫描枪触发Enter提交时,processingSubmit会被立刻置为true,按钮瞬间进入禁用状态,后续用户手动点击按钮时,因为按钮处于disabled状态,点击事件不会被触发,完全避免重复提交问题,同时保留了原生Enter键提交的能力。
内容的提问来源于stack exchange,提问作者user2687103
相关产品推荐
相关产品推荐

