Как правильно использовать эти подписки RxJs?

Итак, у меня есть вопрос о механике Angular и RxJs. У меня есть разбиение на страницы на стороне сервера на моем бэкэнде, и у меня есть три компонента на внешнем интерфейсе: 1) список с данными, 2) некоторые фильтры, 3) компонент разбиения на страницы. Как подписаться на два потока (разбиение на страницы и фильтры) для вызова метода getAll с новыми параметрами из этих компонентов? Возможно, мне следует использовать оператор CombineLatest? Это верно? Как я могу улучшить его?

const pagSettingsSub = this.paginatorSrv.subscriber$
      .pipe(
        tap(data => {
          this.pagSettings = data
        })
      )
    const filterSettingsSub = this.filterAndSortSrv.subscriber$
      .pipe(
        tap(data => this.filterAndSortSettings = data)
      )

    combineLatest([pagSettingsSub, filterSettingsSub])
      .pipe(
        tap(() => this.isLoading$.next(true)),
        mergeMap(() => this.messageSrv.getAll(this.pagSettings, this.filterAndSortSettings)),
        takeUntil(this.destroy$)
      )
      .subscribe({
        next: () => this.isLoading$.next(false),
        error: () => this.isLoading$.next(false),
        complete: () => this.isLoading$.next(false)
      })`
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Да, вы можете использовать оператор combLatest, чтобы объединить потоки из ваших компонентов разбивки на страницы и фильтров и инициировать новый запрос к вашему серверу всякий раз, когда любой из этих потоков выдает новое значение.

Но поскольку вы упомянули в комментариях к этому ответу, что вам также потребуется сбросить нумерацию страниц при изменении фильтра, я бы рекомендовал вам подойти к этому следующим образом:

const resultData = this.filterAndSortSrv.subscriber$.pipe(
    tap(() => this.paginationSrv.resetPage()),
    switchMap((filterSettings) => combineLatest([of(filterSettings), this.paginatorSrv.subscriber$])),
    tap(() => this.isLoading$.next(true)),
    switchMap(([filterSettings, pageSettings]) => this.messageSrv.getAll(pageSettings, filterSettings)),
    takeUntil(this.destroy$),
    catchError(error => {
         // do error handling stuff
    }),
    finalize(() => this.isLoading$.next(false))
)

Вот что происходит в этом коде:

  1. Мы создаем две наблюдаемые, одну для настроек разбивки на страницы и одну для настроек фильтра. Эти наблюдаемые излучаются всякий раз, когда соответствующие настройки изменяются в компонентах разбивки на страницы и фильтров.
  2. Мы проходим через наблюдаемый фильтр, чтобы всегда сбрасывать разбиение на страницы при каждом изменении фильтра.
  3. Мы используем combLatest, чтобы объединить эти два наблюдаемых объекта в один наблюдаемый объект, который генерируется всякий раз, когда изменяется любой из параметров компонента.
  4. Мы используем tap, чтобы установить объект isLoading$ в true всякий раз, когда комбинированный наблюдаемый испускает.
  5. Мы используем switchMap, чтобы сделать новый запрос к серверу, используя последние настройки разбивки на страницы и фильтрации всякий раз, когда испускается комбинированный наблюдаемый объект.
  6. Мы используем takeUntil, чтобы гарантировать отмену подписки при уничтожении компонента.
  7. Используйте оператор catchError для обработки исключений
  8. Мы используем finalize, чтобы установить объект isLoading$ в false всякий раз, когда наблюдаемое завершается или возникает ошибка.

Этот код должен хорошо работать для вашего варианта использования. Однако вы также можете рассмотреть возможность использования операторов debounceTime или DifferentUntilChanged, чтобы предотвратить выполнение ненужных запросов к серверу, если пользователь вводит фильтр или часто меняет параметры разбиения на страницы. Эти операторы могут помочь уменьшить количество запросов, отправляемых на сервер, в результате чего пользовательский интерфейс становится более отзывчивым и эффективным.

Теперь вы можете использовать этот оператор с асинхронным каналом в вашем html!

Так полезный ответ, спасибо. Но загрузка все равно верная, что не так?

Air_O 17.04.2023 19:37

Я отредактировал свой ответ, надеюсь, теперь это сработает! Примечание: rxjs-course.dev/course/error-handling/finalize-operator

Don 17.04.2023 19:43

Вы спасли мой день! И последний момент, который я хотел бы уточнить, — как бы вы сбрасывали нумерацию страниц при использовании фильтров?

Air_O 17.04.2023 19:57

Я полагаю, что под сбросом нумерации страниц вы имеете в виду сброс на страницу 1? Вы можете добавить метод внутри paginatorSrv, который сбрасывает тему paginator (источник paginatorSrv.subscriber$). Вот так: resetPagination() { this.subject.next({page: 1}); } Отвечает ли это на ваш вопрос?

Don 17.04.2023 20:01

Да я так же думаю

Air_O 17.04.2023 20:05

Я обновил свой ответ, чтобы он соответствовал вашим требованиям. Наблюдаемый фильтр теперь запускает сброс страницы при изменении! Надеюсь, это то, что вам нужно.

Don 17.04.2023 20:12

Другие вопросы по теме