Итак, у меня есть вопрос о механике 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)
})`
Да, вы можете использовать оператор 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))
)
Вот что происходит в этом коде:
Этот код должен хорошо работать для вашего варианта использования. Однако вы также можете рассмотреть возможность использования операторов debounceTime или DifferentUntilChanged, чтобы предотвратить выполнение ненужных запросов к серверу, если пользователь вводит фильтр или часто меняет параметры разбиения на страницы. Эти операторы могут помочь уменьшить количество запросов, отправляемых на сервер, в результате чего пользовательский интерфейс становится более отзывчивым и эффективным.
Теперь вы можете использовать этот оператор с асинхронным каналом в вашем html!
Я отредактировал свой ответ, надеюсь, теперь это сработает! Примечание: rxjs-course.dev/course/error-handling/finalize-operator
Вы спасли мой день! И последний момент, который я хотел бы уточнить, — как бы вы сбрасывали нумерацию страниц при использовании фильтров?
Я полагаю, что под сбросом нумерации страниц вы имеете в виду сброс на страницу 1? Вы можете добавить метод внутри paginatorSrv, который сбрасывает тему paginator (источник paginatorSrv.subscriber$). Вот так: resetPagination() { this.subject.next({page: 1}); } Отвечает ли это на ваш вопрос?
Да я так же думаю
Я обновил свой ответ, чтобы он соответствовал вашим требованиям. Наблюдаемый фильтр теперь запускает сброс страницы при изменении! Надеюсь, это то, что вам нужно.
Так полезный ответ, спасибо. Но загрузка все равно верная, что не так?