如何仅获取Angular 6 rxjs中的最后一个可观察到的输出

时间:2019-07-18 08:05:41

标签: angular rxjs

我有一个可观察的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 }));
                    }
                })
            }
        });
    }
}

2 个答案:

答案 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();
    }
}