订阅每个页面的rxjs分页

时间:2018-07-04 13:31:33

标签: typescript rxjs graphql apollo rxjs6

我们正在通过websocket查询graphql来订阅实体列表。我们使用分页,因为该列表应该可以无限滚动。我们还希望在前端列表中实时查看db中所做的更改。

此列表可以是filteredsortedpaginated

我们有SelectParams类,可以帮助我们做到这一点:

export class SelectParams {
    page = 0;
    query = '';
    sort: Sort = { sortBy: 'creationDate', sortOrder: 'DESC' };
    take = 30;
}

然后,当我们要订阅列表时,只给selectParams$ = Observable<SelectParams>即可获得“活动”列表并对selectParams$中的更改做出反应。这样使用:

    this.items$ = this.featureSrv.selectMany(this.selectParams$)

selectMany的内幕如下:

// when we call selectMany we just push the params to the pipeline
selectMany(params$: Observable<SelectParams> = of(new SelectParams())): Observable<T[]> {
    this.selectManyParams$.next(params$);
    return this.selectMany$;
}

// subject where we push params to sort, paginate and filter
selectManyParams$ = new ReplaySubject<Observable<SelectParams>>(1);
// when the params change then so does this observable, which is returned by the selectMany function
selectMany$ = this.selectManyParams$.asObservable().pipe(
    // retrieve params from their observable form
    flatMap(params$ => params$),
    // when the params haven't changed we shouldn't do anything
    distinctUntilChanged(),
    // then we query graphql to get a suscription to some part of the data
    switchMap(({ page, sort, query, take }: SelectParams) => {
    // the selectMany here is a subscription to some data on the server
        return this.apolloWrapper.selectMany(this.gql, page, sort, query, take ).pipe(
    // we add page data so we can use it in the scan
            map(data => ({ data, page }) as any)
        );
    }),
    // we append the result if page was incremented
    // else we just return the result
    scan((acc: any, curr: any) => curr.page === 0 ? curr.data : acc.concat(curr.data), [])
);

方法this.apolloWrapper.selectMany是我们创建的一种方法,该方法仅通过websocket对某些数据片段进行预订。 假设我们有page = 0,然后this.apolloWrapper.selectMany将返回对第一数据切片的预订,然后当page = 1this.apolloWrapper.selectMany返回对第二数据切片的预订。

当我们加载第二页并对第一个切片的项目进行修改时,就会出现问题,然后触发scan并将项目读到列表的末尾。

0 个答案:

没有答案