You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 07:05:27