如何让RxJS startWith仅作用于嵌套data数组而非分页数据?
实现方案:让startWith(null)仅作用于数据列表,保留分页组件显示
当前代码通过startWith(null)在分页切换时清空数据以显示骨架屏,但同时会导致分页组件被清空。以下两种方案可实现startWith(null)仅影响数据列表,分页组件保持显示直到新数据返回。
方案1:拆分独立数据流(推荐)
将数据列表与分页信息拆分为两个Observable,分别控制各自的状态:
TypeScript 代码修改
// 基础响应流:共享订阅避免重复发起HTTP请求 private universityApplicationsResponse$ = this.activatedRoute.queryParams.pipe( switchMap((obj) => this.httpService.getUniversityApplicationsList(this.numberOfRows, new URLSearchParams(obj).toString()) ), shareReplay(1) ); // 数据列表流:仅对data字段使用startWith(null),触发骨架屏显示 universityApplicationsData$ = this.universityApplicationsResponse$.pipe( map(res => res.data), startWith(null) ); // 分页信息流:无startWith逻辑,始终保留最新有效分页数据 universityApplicationsPagination$ = this.universityApplicationsResponse$.pipe( map(res => res.pagination) );
HTML 代码修改
<div class="skeleton-y5ha4dikw8f"> <ng-container *ngIf="(universityApplicationsData$ | async) as uniData"> <!-- uniData为null时显示骨架屏,否则渲染表格 --> <p-table *ngIf="uniData; else skeleton" [value]="uniData"> <ng-template pTemplate="header"> <tr> <th>Application name</th> <th>University</th> </tr> </ng-template> <ng-template pTemplate="body" let-detail> <tr> <td>{{detail.name}}</td> <td>{{detail.university_name}}</td> </tr> </ng-template> </p-table> <ng-template #skeleton> <div class="skeleton-y5ha4dikw8f"></div> </ng-template> </ng-container> </div> <!-- 分页组件绑定分页流,始终显示最新有效值 --> <p-paginator *ngIf="(universityApplicationsPagination$ | async) as paginationData" [rows]="numberOfRows" [first]="paginationData.current_page" [totalRecords]="paginationData.total" (onPageChange)="paginate($event)" #pp></p-paginator>
方案2:使用scan累积状态
通过scan操作符保留分页信息的历史状态,仅清空数据列表:
TypeScript 代码修改
universityApplications$ = this.activatedRoute.queryParams.pipe( switchMap((obj) => // 先发出data为null的临时对象(触发骨架屏),再发出HTTP请求响应 concat( of({ data: null }), this.httpService.getUniversityApplicationsList(this.numberOfRows, new URLSearchParams(obj).toString()) ) ), // 累积状态:保留上一次的分页数据,仅更新data字段 scan((prevState, currState) => ({ data: currState.data ?? prevState.data, pagination: currState.pagination ?? prevState.pagination }), { data: null, pagination: {} }) );
HTML 代码说明
原HTML结构无需修改,此时(universityApplications$ | async)?.pagination会始终保留上一次的有效值,直到新的分页数据返回,分页组件不会消失。
内容的提问来源于stack exchange,提问作者Andrew Howard
相关产品推荐
相关产品推荐

