angularjs - Angular,当用户单击按钮或多次提交时如何处理?
问题描述
如何防止用户多次提交表单?我目前的问题是当用户多次单击提交按钮时,它将创建多个用户。它应该只创建一次用户并在创建另一个用户之前等待。
这是我所拥有的:
<button mat-flat-button color="primary" [disabled]="userStatus == 'USER_EXISTS_ON_CURRENT_ACCOUNT'" (click)="createUser()">Create
User</button>
打字稿:
createUser() {
this.accountService.create(this.modelForm.value).pipe(
finalize(() => {
this.isInProgress = false;
})
).subscribe({next: (res) => { this.notificationService.showSuccess('User has been created successfully.');
this._router.navigate(['settings/user']);
},
error: (err) => {this.notificationService.showError('Something went wrong, Try again later.');
this.isInProgress = false;
},
complete: () => {
this.isInProgress = false;
},
});
}
解决方案
我稍微更新了你的代码,
1 - 我们必须在模板中创建一个用户按钮
<button #createUserBtn mat-flat-button color="primary" [disabled]="userStatus == 'USER_EXISTS_ON_CURRENT_ACCOUNT'"> CreateUser </button>
2 - 访问 .ts 文件中的创建用户按钮
@ViewChild('createUserBtn', {static:true}) button;
3 - 创建变量clicks$
来存储点击事件
clicks$: Observable<any>;
4 - 在 ngOnInit 中:初始化clicks$
变量以监听点击事件
this.clicks$ = fromEvent(this.button.nativeElement, 'click');
5 - 在 ngOnInit 中:在每个点击事件上,即从click$
我们将我们的事件传递给exhaustMap
排气映射的美妙之处在于,一旦第一个(外部可观察)事件被触发,它将停止监听事件(外部可观察),直到完成其内部可观察
所以在我们的例子中,当用户第一次点击按钮(事件)时,exhaustMap
将停止监听按钮点击事件,直到它完成我们的 API 调用createUser()
。我们将使用该handleResponse()
方法处理这个 API 调用 observable。
ngOnInit() {
this.clicks$ = fromEvent(this.button.nativeElement, 'click');
const result$ = this.clicks$.pipe(
tap(x => console.log('clicked.')),
exhaustMap(ev => {
console.log(`processing API call`);
return this.createUser();
})
);
result$.subscribe(this.handleResponse());
}
创建用户 API 调用
createUser(): Observable<any> {
return this.accountService.create(this.modelForm.value).pipe(
finalize(() => (this.isInProgress = false))
);
}
处理响应
handleResponse(): any {
return {
next: res => {
this.notificationService.showSuccess('User has been created successfully.');
this._router.navigate(['settings/user']);
},
error: err => {
this.notificationService.showError('Something went wrong, Try again later.');
this.isInProgress = false;
}
complete: () => this.isInProgress = false;
};
}
如果您无法访问按钮,您可以将 ngOnit 代码移动到AfterViewInit
让我知道是否有任何错误,因为我尚未完全测试您的代码。
ngAfterViewInit(): void {
fromEvent(this.button.nativeElement, 'click')
.pipe(
tap(x => console.log('clicked.')),
exhaustMap(ev => {
console.log(`processing API call`);
return this.createUser();
})
)
.pipe(tap(x => console.log('Api call completed....')))
.subscribe(this.handleResponse());
}
推荐阅读
- flutter - Flutter SnackBar leaves an invisible padding in the Scaffold
- python - 如何重复 python 行以运行命令?
- java - How to write mapper(MapStruct) from a list type to a list
- python - 将列表列表作为参数传递给 select (x,y) in 子句
- javascript - Discord.js try to read file in place of sending it
- flutter - Unable to log event: analytics library is missing
- python - VSCode Kivy 2.0.1 不起作用(无法找到窗口)
- excel - XLOOKUP [if_not_found] 参数
- html - 用 sass / css 替换所有 html 中的一个字符
- javascript - 如何检查值是否在数组中是多个或不是在Javascript中?