我有一个可观察的form.valueChanges来自不同的组件。
我需要第一个输出来将工具栏标题设置为可见的window.dispatchEvent(new CustomEvent('showHeader', { detail: true }))
之后,我需要等待用户输入status
。
这是我的挑战:当status === true
时,我只想要最后一个可观察到的输出(因为它包含所有表单更改)。此处显示的代码有效,但每个可观察的输出保存一次。
我花了数小时浏览rxjs文档,并在SO上无济于事。我曾尝试切换到Subject,但这显然不是走的路,还有其他几次尝试,现在我很确定(!)publishReplay
是解决方案,但我无法使其正常工作。
import { debounceTime, publishRelay } from 'rxjs/operators';
import { Directive, Output, Input, EventEmitter, OnInit } from '@angular/core';
import { SaveService } from './save.service';
@Directive({
selector: '[save]'
})
export class SaveDirective implements OnInit {
@Input() public save: any;
@Output() public appSubmit: EventEmitter<any> = new EventEmitter<any>();
@Input() public debounce = 500;
constructor(private saveService: SaveService) { }
ngOnInit() {
this.save.form.valueChanges
.pipe(debounceTime(this.debounce))
// .publishReplay(1).refCount()
.subscribe((data: any) => {
if (this.save.valid && !this.save.pristine) {
window.dispatchEvent(new CustomEvent('showHeader', { detail: true }));
this.saveService.currentStatus$.subscribe((status: boolean) => {
if (status) {
this.appSubmit.emit({ data });
this.saveService.changeStatus(false);
window.dispatchEvent(new CustomEvent('showHeader', { detail: false }));
}
})
}
});
}
}
答案 0 :(得分:1)
ngOnInit() {
this.save.form.valueChanges
.pipe(
debounceTime(this.debounce),
tap((value)=> {
if(!this.status) never();
else of(value);
}),
mergeMap((value)=>{
return this.saveService.currentStatuss;
})
).subscribe(data=> {
this.appSubmit.emit({ data });
this.saveService.changeStatus(false);
window.dispatchEvent(new CustomEvent('showHeader', { detail: false }));
})
您可以在管道中检查是否要继续进行tp。希望这会有所帮助。 帮助https://blog.strongbrew.io/rxjs-patterns-conditionally-executing-work/
答案 1 :(得分:0)
仍然缺少一些细节,但这可以完成工作
import { debounceTime, map, switchMap } from 'rxjs/operators';
import { Directive, Output, Input, EventEmitter, OnInit } from '@angular/core';
import { NEVER } from 'rxjs';
import { SaveService } from './save.service';
@Directive({
selector: '[appSave]'
})
export class SaveDirective implements OnInit {
@Input() public appSave: any;
@Output() public submit: EventEmitter<any> = new EventEmitter<any>();
@Input() public debounce = 500;
constructor(private saveService: SaveService) { }
ngOnInit() {
this.appSave.form.valueChanges
.pipe(
debounceTime(this.debounce),
switchMap(data => {
if (this.appSave.valid && !this.appSave.pristine) {
window.dispatchEvent(new CustomEvent('showHeader', { detail: true }));
return this.saveService.currentStatus$.pipe(
map(status => {
if (status === 'save') {
this.submit.emit({ data });
status = 'false';
this.saveService.changeStatus('false');
window.dispatchEvent(new CustomEvent('showHeader', { detail: false }));
this.appSave.form.markAsPristine();
} else if (status === 'discard') {
console.log('Discarded. Reset form!');
status = 'false';
this.saveService.changeStatus('false');
window.dispatchEvent(new CustomEvent('showHeader', { detail: false }));
return NEVER;
}
})
);
} else {
return NEVER;
}
})
)
.subscribe();
}
}