Как мне дождаться нескольких результатов, а затем отфильтровать их по полученным данным? - PullRequest
3 голосов
/ 29 мая 2019

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

this.allValues$ = this.store.select(selectors.getAllValues)
this.myId$ = this.store.select(selectors.myId)

и я могу отобразить их в шаблон с помощью асинхронного канала

Однако я хотел бы создать свойство класса, которое содержит фильтрованный массив. Если бы это был синхронный JS, что-то вроде

this.filteredResults = allValues.filter(value => value.id === myId)

zip Я получу значения

this.filteredResults$ = zip(
  this.store.select(selectors.getAllValues),
  this.store.select(selectors.myId)
)

шаблон: результаты: {{FilterResults $ | асинхронный | json}}

Но я не могу понять, как фильтровать, как я хочу. Я пытался связать pipe с zip:

.pipe(
   tap((...args) => {
     console.log({ args }) // only one result so no hope of dropping in `map` or `filter` here
   })
)

Но это приводит к удалению массива allValues из набора результатов. allValues значительно больше, поэтому, вероятно, потребуется больше времени, и zip больше не ждет, пока все испустит, поэтому я думаю, pipe не является решением, хотя кажется, что оно близко.

Как я могу получить доступ к обоим наборам результатов, отфильтровать их и поместить этот результат в наблюдаемое, которое я могу отобразить в шаблоне с помощью filteredResults$ | async | json?

Ответы [ 3 ]

0 голосов
/ 29 мая 2019

Вы можете использовать оператор forkJoin.

Документы: https://www.learnrxjs.io/operators/combination/forkjoin.html

Примеры: https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs

Аналогичный пост переполнения стека: rxjs - объединение внутренних наблюдаемых после фильтрации

" Оператор forkJoin () позволяет нам взять список Observables и выполнить их параллельно. Как только каждый Observable в списке выдаст значение, forkJoin выдаст одно значение Observable, содержащее список всех разрешенные значения из наблюдаемых в списке"

Приветствия

0 голосов
/ 29 мая 2019

Легко не заметить NgRx селекторы. Вы должны проверить документацию, потому что то, что вы пытаетесь достичь, возможно с помощью метода createSelector. Это будет иметь множество преимуществ (более чистый код, многоразовый селектор и т. Д.)

https://ngrx.io/guide/store/selectors#using-selectors-for-multiple-pieces-of-state

Нечто подобное может работать в вашем случае:

export const yourCombinedSelector = createSelector(
  selectors.getAllValues,
  selectors.myId,
  (allValues, myId) => {
    // perform logic and return the data you need
  }
);

Тогда

const data$ = this.store.select(selectors.yourCombinedSelector)
0 голосов
/ 29 мая 2019

Вы можете использовать concatMap или switchMap.

this.filteredResults = this.store.select(selectors.myId).pipe(
  concatMap(myId => {
    return this.store
      .select(selectors.getAllValues)
      .pipe(filter(value => value.id === myId));
  })
);
...