Javascript 如何使用RxJS正确实现一次点击激活操作按钮?
我还在学习RxJS。对于我的一个项目,我想实现这个“只保存一次”功能 关于RxJs的视频中的代码片段如下:Javascript 如何使用RxJS正确实现一次点击激活操作按钮?,javascript,angular,typescript,rxjs,observable,Javascript,Angular,Typescript,Rxjs,Observable,我还在学习RxJS。对于我的一个项目,我想实现这个“只保存一次”功能 关于RxJs的视频中的代码片段如下: const clickToSave$ = saveClick$.pipe( exhaustMap(() => http.post(saveURL, data) ) ) 我有以下重写的代码,其中我尝试将代码片段实现到现有的代码库中 const saveClick$ = new Observable(); // TODO: error handling con
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);
});
}
…但它显然不起作用。我应该如何绑定到按钮HTML中的(单击)=..
事件?
总而言之,我想要的是,理论上你可以点击按钮,但它会在一段时间内只做一次操作(在本例中是
http.post
call),因此当用户通过点击发送按钮时。我如何才能成功地为我自己的特定用例实现这个代码片段(我想未来很多人也会寻找这个用例)。如果需要更多解释,请随时提问
模板
<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));
}
}
保存按钮
保存按钮2
代码
<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));
}
}
导出类AppComponent实现OnInit{
//解决方案1-个人不太喜欢这个,但它确实有效
//手动确保订阅在允许新订阅之前完成
activeSubscription:订阅;
bntClicked($event){
如果(!this.activeSubscription){
this.activeSubscription=this.saveMock().subscripte({
下一步:结果=>{
控制台日志(结果);
这是resetSubscription();
}
});
}
}
重置订阅(){
this.activeSubscription.unsubscripte();
this.activeSubscription=未定义;
}
//最终解决方案1;
//解决方案2-我更喜欢这个
//我们使用ViewChild获得对按钮的引用
@ViewChild(“btn”,{static:true})按钮:ElementRef;
ngOnInit():void{
//选择1
fromEvent(this.button.nativeElement,“单击”)
.烟斗(
//取消以前的可观察项并订阅新的/最后一个
switchMap($event=>this.saveMock())
)
.订阅({
下一步:result=>console.log(“开关映射”,result)
});
//选择2
fromEvent(this.button.nativeElement,“单击”)
.烟斗(
去BounceTime(1000),
mergeMap($event=>this.saveMock())
)
.订阅({
下一步:result=>console.log(“debounceTime”,result)
});
}
//最终解决方案2;
saveMock():可观察