typescript - Cum să folosești mergeWith cu Subjects în Angular


Scop: Un filtru combinat cu 3 intrări pentru a filtra o listă

Restricții:

  • Utilizatorul nu ar trebui să fie forțat să completeze toate filtrele disponibile pentru a trimite
  • Prima trimitere ar trebui să aibă loc odată ce utilizatorul introduce
  • Intrările diferite sunt combinate odată ce există mai mult de una

Punctul meu de vedere: Trimit datele de intrare de la cele 3 componente de intrare diferite către Subjects într-un Serviciu care ar trebui să acționeze ca emițător de evenimente între intrare și combinația efectivă, pentru a putea reutiliza și a selecta diferite intrări după cum este necesar

export class FilterInputStoreService {
  public selectedTypesHandler = new Subject<string>();
  public selectedPrivacyOptionsHandler = new Subject<boolean>();
  public searchInputHandler = new Subject<boolean>();
  constructor() {}
}

În componenta de combinare a filtrelor încerc să „ascult” dacă un subiect trimite ceva și să îl combin cu restul folosind mergeWith.

this.filterInputStore.selectedTypesHandler
    .mergeWith(this.filterInputStore.searchInputHandler, this.filterInputStore.selectedCurrenciesHandler )
    .map(() => {
       this.combinedDataObject = {
       Here i combine the values, doesnt matter for the question
        };
         }),
        tap(() => {
          this.filterService.newFilterData(this.combinedDataObject);
        })
       )
        .subscribe();

Problemă:

  • Se spune că mergeWith nu poate fi folosit cu Subject-uri
  • Alți operatori precum combineLatest nu funcționează deoarece necesită să aștepte până când fiecare dintre surse are o intrare.
  • Nu pot folosi BehaviorSubject pentru că acesta emite o valoare inițială care este null, ceea ce face ca filtrul să se prăbușească

Răspuns #1

mergeWith, la fel ca merge, funcționează perfect cu Subjects.

Exemplu :

import { Subject } from 'rxjs';
import { mergeWith } from 'rxjs/operators';

const s1 = new Subject<string>();
const s2 = new Subject<string>();
const s3 = new Subject<string>();

s1.pipe(mergeWith(s2, s3)).subscribe(console.log);


s1.next('1')
s2.next('12')
s3.next('123')

// output 1, 12, 123. 

Stackblitz