RX JS объединяет потоки сортировки и разбивки на страницы - PullRequest
1 голос
/ 04 марта 2020

Итак, я изучал RX JS, но с этим немного борюсь. У меня есть исходящий поток пагинации, который вызывает next на behaviorSubject, инициализирован запросом по умолчанию, запускает другой поток.

Все это прекрасно работает, а нумерация страниц разбивается на части с scan, что является желаемым результатом. как нумерация страниц из бесконечной прокрутки.

Теперь мне нужно добавить поток сортировки, где страница должна быть сброшена до 0, а элементы не должны добавляться к существующим, что в настоящее время достигается через scan. Я не могу добавить фильтр. Как мне этого добиться?

    const items$ = this.queryChange$.pipe(
      switchMap((input: ItemQueryInput) => this.getAll$(input)),
    );

    const loadMoreItems$ = items$.pipe(
      scan<any>((acc, src) => acc.concat(src)),
      share(),
      tap((items) => console.warn('paginated', items)),
    );

    this.itemsRefresh$$ = loadMoreItems$.pipe(
      tap(items => {
        this.data = items;
        this.pageOffset = Math.ceil(items.length / LIMIT) + 1);
      })
    ).subscribe();

   private onPageNumberChange(pageNumber: number) {
    const query = _.merge({}, DEFAULT_QUERY, {
      pageOffset,
      sortBy: this.sortBy,
    } as ItemQueryInput);

    this.queryChange$.next(query);
  }

   private onSortChange(sort: SortEvent) {
    const { active, direction } = sort;
    const sortBy = this.sortBy = !_.isEmpty(direction) ? { field: active, order: direction } : null;
    const query = _.merge({}, DEFAULT_QUERY, {
      sortBy,
    } as ItemQueryInput);

    this.sortEvent$.next(true);
    this.queryChange$.next(query);
  }

При попытке сделать это был описан выше и ваши комментарии, я попытался использовать filter, чтобы он испускал только если сортировка передается во входных данных запроса.

Однако результат все тот же, разбиение на страницы работает, пока sort не установлен. После сортировки элементы обновляются, но разбиение на страницы больше не срабатывает. Не могу понять, почему.

[EDIT]

    const paginatedItems$ = this.queryChange$.pipe(
      tap((query) => console.warn('paginated filter condition', _.isNil(query.sortBy) || query.pageOffset !== 1)),
      filter((query) => _.isNil(query.sortBy) || query.pageOffset !== 1),
      switchMap((query) => this.getAll$(query)),
      scan<any>((acc, src) => acc.concat(src)),
      tap((items) => this.pageOffset = _.round((items.length / LIMIT) + 1)),
      tap((items) => console.warn('paginated items, next pageoffset', items, this.pageOffset)),
    );

    const sortedItems$ = this.queryChange$.pipe(
      tap((query) => console.warn('sorted filter condition', !_.isNil(query.sortBy) || query.pageOffset === 1)),
      filter((query) => !_.isNil(query.sortBy) && query.pageOffset === 1),
      switchMap((query) => this.getAll$(query)),
      tap(() => this.pageOffset = 1),
      tap((items) => console.warn('sorted items, next pageOffset', items, this.pageOffset)),
    );

    const loadMoreItems$ = merge(paginatedItems$, sortedItems$).pipe(
      tap((items) => console.warn('loadedItems', items)),
    );

    this.loadMoreItems$$ = loadMoreItems$.pipe(
      tap(books => this.data = items)
    ).subscribe();

Дополнительная информация

Желаемое поведение:

  • накапливать результаты при изменении pageOffset (вести себя как бесконечная прокрутка)
  • заменять результаты при изменении сортировки (и сбрасывать pageOffset) и снова начинать разбиение на страницы с нового.

enter image description here

...