javascript - 如何使用 RxJS 正确实现一次在时间范围内单击激活的操作按钮?
问题描述
我还在学习 RxJS。对于我的一个项目,我想实现这个“只保存一次”功能。
关于 RxJs 的视频中的代码片段如下:
const clickToSave$ = saveClick$.pipe(
exhaustMap(() => http.post(saveURL, data) )
)
我有以下重写的代码,其中我尝试将代码片段实现到我现有的代码库中。
const saveClick$ = new Observable();
// TODO: error handling
const clickToSave$ = saveClick$.pipe( exhaustMap(() => this.http.post(this.xmlendpointPdf, jsonType, this.httpOptions) )
).subscribe(
result => {
const docUrl = 'test';
console.log(docUrl); },
error => {
if (error['status'] === 0) {
this.openAlertDialog('Unknown error');
} else {
this.openAlertDialog('The following error has appeared:' + error['statusText']);
}
console.log('There was an error: ', error);
});
}
...但它显然不起作用。我应该如何绑定到(click)= ....
按钮 HTML 中的事件?回顾一下,我想要的是理论上你可以尽可能多地点击按钮,但它只会http.post
在一段时间内执行一次操作(在这种情况下是调用),所以当用户通过点击向按钮发送垃圾邮件时。我怎样才能为我自己的特定用例成功实现这个代码片段(我想未来很多人也会寻找它)。
解决方案
如果您需要更多解释,请随时提出问题!
模板
<button (click)="bntClicked($event)">Save Button</button>
<br />
<button #btn>Save Button 2</button>
代码
export class AppComponent implements OnInit {
//Solution 1 - Not a big fan of this one personally but it does work
//Manually make sure a subscription finishes before allowing a new one
activeSubscription: Subscription;
bntClicked($event) {
if (!this.activeSubscription) {
this.activeSubscription = this.saveMock().subscribe({
next: result => {
console.log(result);
this.resetSubscription();
}
});
}
}
resetSubscription() {
this.activeSubscription.unsubscribe();
this.activeSubscription = undefined;
}
//End solution 1;
//Solution 2 - I prefer this one
//We get a reference to the button using ViewChild
@ViewChild("btn", { static: true }) button: ElementRef;
ngOnInit(): void {
//Option 1
fromEvent(this.button.nativeElement, "click")
.pipe(
//Cancel previous observable and subscribe to new/last one
switchMap($event => this.saveMock())
)
.subscribe({
next: result => console.log("switchMap", result)
});
//Option 2
fromEvent(this.button.nativeElement, "click")
.pipe(
debounceTime(1000),
mergeMap($event => this.saveMock())
)
.subscribe({
next: result => console.log("debounceTime", result)
});
}
//End solution 2;
saveMock(): Observable<any> {
return of({ description: "Hello World!" }).pipe(delay(1000));
}
}
资源
推荐阅读
- sql - 在 SQL 中将多个列一起旋转
- java - 聚合后缺少最后一组
- javascript - 如何在没有按钮的情况下在本地存储中保存两个复选框之一
- c# - 如何在 ASP.NET CORE 2.2 中将变量从表单传递到 ajax
- mongodb - 如何从 MongoDB 集合中的文档中提取前 n 个元素?
- python - Python2中的非阻塞“等待按键”功能
- azure - 通过 Kubernetes 挂载卷时 Neo4j 关闭
- docker - 用于离线镜像的 Docker DCT
- cakephp - 如何保存重复记录使用belongsToMany?
- javascript - Service Worker 只显示第一个推送通知(来自云消息传递),直到我重新加载 - 消息已被工作人员收到