【问题标题】:rxjs - startWith based on Observable with initial valuerxjs - startWith 基于 Observable 的初始值
【发布时间】:2021-01-13 07:21:45
【问题描述】:

我有一个具有查询、排序和分页功能的数据源。所有这些都被定义为 BehaviourSubjects。我正在尝试实现状态保存表,恢复查询,排序和分页值。

目前我有下面的代码负责它:

// params restored from storage
const pageSize = this.params.page?.pageSize ?? 20;
this.pageIndex = this.params.page?.pageIndex ?? 0;

query = new BehaviorSubject<Q | undefined>(params.query);
sort = new BehaviorSubject<Sort<T> | undefined>(params.sort);
page = new Subject<PageEvent>();

管理数据查询的代码:

combineLatest([this.query, this.sort])
.pipe(
  switchMap(([query, sort]) => this.page.pipe(
    // combine pageIndex: 0 for query, sort change
    startWith({ pageIndex: this.pageIndex, pageSize } as PageEvent), 
    map(page => [
      this.storeParams({ query, sort, page }),
      this.store.dispatch(
        this.selectAction({ query, page: page.pageIndex, sort, size: page.pageSize })
      )
    ]),
    catchError(error => of()),
  ))
);

它可以正常工作,但是当排序或查询值发生变化时,我需要将 pageIndex 重置为 0。如果我使用 startWith 且 pageIndex 等于 0,那么我将失去从存储中恢复页面值的能力。

为了实现它,我在排序和查询功能上重置了 pageIndex:

sortBy(sort: Sort<T>): void {
  this.pageIndex = 0; // need to remove
  this.sort.next(sort);
}

queryBy(query: Partial<Q>): void {
  this.pageIndex = 0; // need to remove
  this.query.next(query as Q);
}

如何使用单个运算符来实现这一点,即上面的 combineLatest?

【问题讨论】:

  • 看起来与我之前回答过的stackoverflow.com/questions/63440800/… 非常相似。
  • 谢谢,但您提到的解决方案与我的非常相似。我只是想摆脱从 sortBy\queryBy 方法重置分页并将其合并到初始运算符中的必要性。
  • 你的整个结构看起来很复杂。为什么要创建自己的内联运算符而不是使用 switchMap?为什么你使用 switchMap 而不是法线贴图?此外,您的流无论如何都取决于副作用,因此您可以在combineLatest 之后直接使用tap 运算符重置值。
  • 很抱歉给您带来了困惑。偶尔会错过第一个 switchMap 运算符。在对代码进行多次操作后,第二个地图运算符仍然存在。我已经更新了它以便更清楚地理解。

标签: angular typescript rxjs ngrx


【解决方案1】:

这样的东西有用吗?每次combineLatest([this.query, this.sort]) 有新值时,只需重置 pageIndex。

combineLatest([this.query, this.sort]).pipe(
  tap(_ => this.pageIndex = 0),
  switchMap(([query, sort]) => this.page.pipe(
    // combine pageIndex: 0 for query, sort change
    startWith({ pageIndex: this.pageIndex, pageSize } as PageEvent), 
    map(page => [
      this.storeParams({ query, sort, page }),
      this.store.dispatch(
        this.selectAction({ 
          query, 
          page: page.pageIndex, 
          sort, 
          size: page.pageSize 
        })
      )
    ]),
    catchError(error => of()),
  ))
);

【讨论】:

    猜你喜欢
    • 2019-06-13
    • 2017-08-22
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 2018-05-04
    相关资源
    最近更新 更多