Как я могу передать два потока данных / наблюдаемых в одном канале? - PullRequest
0 голосов
/ 17 октября 2019

У меня есть две формы в одном представлении, каждый вывод изменяется. У меня есть глобальная директива с двумя селекторами для получения обоих потоков.

Я легко могу обработать одну форму, но когда у меня есть две, и помещаю каждую в свою собственную трубу или директиву, они портят друг друга, сохраняя функцию, поэтомуговорить, поэтому мне нужно оба в одной трубе. (Или другое решение;)

Компонент формы

<form name="shop_info"
      autocomplete="off"
      #f1="ngForm"
      (SubmitShop)="save($event)"
      [SaveShop]="f1"
      *ngIf="merchant">
...
</form>
...
<form name="region"
      autocomplete="off"
      #f2="ngForm"
      (SubmitRegion)="save($event)"
      [SaveRegion]="f2">
...
</form>

Директива с одним потоком:

@Directive({
    selector: '[SaveShop], [SaveRegion]'
})
export class SaveMerchantDirective implements OnInit {
    @Input() SaveShop: any;
    @Input() SaveRegion: any;
    @Output() SubmitShop: EventEmitter<any> = new EventEmitter<any>();
    @Output() SubmitRegion: EventEmitter<any> = new EventEmitter<any>();
    @Input() debounce = 350;

    constructor(
        private saveService: SaveService,
        private $transitions: TransitionService
    ) { }

    ngOnInit() {
this.saveRegion.form.valueChanges
    .pipe(
        debounceTime(this.debounce),
        switchMap((data: Object) => {
            if (!sessionStorage.getItem('dataRegion') || sessionStorage.getItem('dataRegion') === '{}') {
                sessionStorage.setItem('dataRegion', JSON.stringify(data));
            }

            this.$transitions.onBefore({}, () => {
                if (this.saveRegion.valid && !this.saveRegion.pristine) {
                    if (confirm(this.translate.instant(
                        'You are about to discard your REGION changes. Click "OK" to discard and navigate away! Click "Cancel" to stay.'
                    ))) {
                        this.discard();
                        return true;
                    } else {
                        return false;
                    }
                }
            });

            if (this.saveRegion.valid && !this.saveRegion.pristine) {
                window.dispatchEvent(new CustomEvent('showHeader', { detail: true }));

                return this.saveService.currentStatus$.pipe(
                    map(status => {
                        if (status === 'save') {
                            this.save(data);
                        } else if (status === 'discard') {
                            this.discard();
                        }
                    })
                );
            } else {
                return NEVER;
            }
        })
    )
    .subscribe();
this.$transitions.onExit({}, () => {
    sessionStorage.removeItem('dataRegion');
    status = 'false';
    this.saveService.changeStatus('false');
});

Как мне справиться с этим?

Могу ли я просто сделать:

combineLatest(this.saveRegion.form.valueChanges, this.saveShop.form.valueChanges)
    .pipe(
        debounceTime(this.debounce),
        switchMap((data: Array<Object>) => {...

Редактировать:

Делать

Observable.combineLatest(
    this.saveShop.form.valueChanges,
    this.saveRegion.form.valueChanges
)
    .subscribe(...

дает Property 'combineLatest' does not exist on type 'typeof Observable'.

Выполнение

combineLatest(
    this.saveShop.form.valueChanges,
    this.saveRegion.form.valueChanges
)
    .subscribe(...

вызывает у меня несколько проблем, когда одна из них заключается в том, что «форма» не может читать неопределенное значение (поскольку два потока не входят одновременно в одинне определено). И если я добавлю startWith(null) я получу this.saveShop.form.valueChanges.startWith is not a function

1 Ответ

0 голосов
/ 17 октября 2019

И если я добавлю startWith (null), я получу this.saveShop.form.valueChanges.startWith не является функцией

Это, по крайней мере, легко решается: это использование операторовустарел ( возможно все равно будет работать, если вы импортировали "правильное" startWith из правильного файла), вместо этого используйте .pipe (как вы делаете с другими операторами: debounceTime, switchMap), поэтому

this.saveRegion.form.valueChanges.pipe(startWith(null)) //...

(в качестве альтернативы concat(of(null), this.saveRegion.form.valueChanges) подойдет).

Другое дело: вы можете filter исключить любые неопределенные / нулевые значения и просто использовать «хорошие вещи»вот так

combineLatest(
    this.saveShop.form.valueChanges.pipe(filter(value => Boolean(value)),
    this.saveRegion.form.valueChanges.pipe(filter(value => Boolean(value)),
//...
...