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

单页面多mat-table场景下如何实现各表网络请求时独立展示加载spinner

实现思路

核心是每个表格独立维护专属的加载状态,加载指示器仅嵌套在对应表格的容器内,和全局/其他表格的状态完全隔离。

具体实现步骤

1. 定义独立的加载状态

不要使用全局通用的isLoading变量,通过数组/对象为每个表格单独存储加载状态,示例代码(TS):

// 表格列表结构,每个项独立维护数据和加载状态
tableList = [
  { id: 'userTable', data: [], loading: false },
  { id: 'orderTable', data: [], loading: false },
  // 其他表格配置
]

// 单个表格的数据拉取方法
getTableData(tableItem: {id: string, data: any[], loading: boolean}) {
  tableItem.loading = true;
  this.http.get(`/api/getData/${tableItem.id}`).subscribe({
    next: (res) => {
      tableItem.data = res;
    },
    error: (err) => {
      // 错误处理逻辑
    },
    complete: () => {
      tableItem.loading = false;
    }
  })
}

2. 模板中绑定对应状态

将spinner嵌套在每个表格的专属容器内,仅根据当前表格的loading属性控制显隐,示例代码(HTML):

<ng-container *ngFor="let table of tableList">
  <!-- 单个表格容器,设置相对定位约束spinner的显示范围 -->
  <div class="table-container" style="position: relative; min-height: 240px;">
    <!-- 加载spinner,仅当前表格加载时显示,居中定位在容器内部 -->
    <mat-progress-spinner
      *ngIf="table.loading"
      mode="indeterminate"
      diameter="48"
      style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 9;"
    ></mat-progress-spinner>

    <!-- 当前表格的mat-table定义 -->
    <mat-table [dataSource]="table.data">
      <!-- 表格列、头部、行定义省略 -->
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
    </mat-table>
  </div>
</ng-container>

3. 适配固定表格的场景

如果页面内的表格是固定写死而非循环渲染的,直接为每个表格声明单独的加载变量即可:

isUserTableLoading = false;
isOrderTableLoading = false;

模板中每个表格的spinner分别绑定对应的变量即可。

注意事项
  • 表格容器必须设置position: relative,避免spinner定位超出当前表格范围
  • 无论请求成功/失败,都要在请求结束时将对应表格的loading状态设为false,避免出现永久加载的问题
  • 可以在加载状态激活时给表格加半透明遮罩,进一步区分状态同时禁止用户操作加载中的表格

内容的提问来源于stack exchange,提问作者priyadarshi kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:24:02