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

Angular Material分页失效求助:动态表格分页不生效

Angular Material分页器无法生效问题排查与解决

我正在跟随Muhi Masri的教程《Load, Add, Update and Delete Table Rows using API Services》(强烈推荐该教程)制作可编辑动态表格。通过日期过滤后使用MatTableDataSource渲染表格数据,但添加Angular Material分页器后完全无法生效,按官方文档操作仍无效果,this.dataSource._filterData.length返回值始终为1。

相关代码

TypeScript代码

// 列配置
displayedColumns: string[] = ActivityColumns.map((col) => col.key);
columnsSchema: any = ActivityColumns;

// 数据源
dataSource = new MatTableDataSource<ApidatumDisplay>();
request: ApidatumDisplay[] = []

getDataIsSelected() {
  let dailydata = {
    startDate: this.selected.startDate.format("YYYY-MM-DD"),
    endDate: this.selected.endDate.format("YYYY-MM-DD")
  }

  const validStartSelected = dailydata.startDate;
  this.editDateisNow = validStartSelected === dayjs().format("YYYY-MM-DD");

  // 请求接口
  this.reportesService.getDailyTracking(dailydata).pipe(takeUntil(this.unsubscribe$)).subscribe((res) => {
    this.request = res.apidata;
    this.dataSource.data = this.request;
    console.log('length', this.dataSource._filterData.length); // 返回1
    this.averageTotal = res.adding_total_activity
    this.hourTimeTotal = this.convert(res.adding_total_hours);
    this.expectedBudget = 192 * 22;
    this.isReload = false;
  });
}

HTML代码

<!--Table of content-->
<section class="rounded mt-2 border overflow-hidden">
  <table mat-table [dataSource]="dataSource">
    <ng-container class="text-uppercase border" [matColumnDef]="col.key" *ngFor="let col of columnsSchema">
      <th class="vertical-align-middle" mat-header-cell *matHeaderCellDef>
        <div class="d-flex align-items-center">
          <div class=" text-size-4 text-overflow mr-1">
            {{ col.label }}
          </div>
        </div>
      </th>
      <td class=" text-size-3 font-weight-regular " mat-cell *matCellDef="let element">
        <div class="text-overflow text-size-4 mr-1" [ngSwitch]="col.type" *ngIf="!element.isEdit">
          <div class="btn-edit" *ngSwitchCase="'isEdit'">
            <button mat-button (click)="element.isEdit=!element.isEdit">
              Editar
            </button>
          </div>
          <span *ngSwitchCase="'text'">
            {{ element[col.key] }}
          </span>
          <span *ngSwitchDefault>
            {{ element[col.key] }}
          </span>
          <div class="text-overflow text-size-4" *ngSwitchCase="'indicator_hour_daily'">
            <img style="height: 12px;" src="https://ymlabqgbnnbvyybcyqjn.supabase.co/storage/v1/object/public/assets-ui/icons/status-{{element.indicator_hour_daily}}.svg" alt="status">
          </div>
          <div class="text-overflow text-size-4" *ngSwitchCase="'indicator_activity_daily'">
            <img style="height: 12px;" src="https://ymlabqgbnnbvyybcyqjn.supabase.co/storage/v1/object/public/assets-ui/icons/status-{{element.indicator_activity_daily}}.svg" alt="status">
          </div>
        </div>
        <div class="text-overflow text-size-4" [ngSwitch]="col.type" *ngIf="element.isEdit">
          <div *ngSwitchCase="'isSelected'"></div>
          <div class="btn-edit" *ngSwitchCase="'isEdit'">
            <button mat-button (click)="editRow(element)">Hecho</button>
            <button mat-button (click)="cancelEditActivity(element)">Cancelar</button>
          </div>
          <mat-form-field *ngSwitchCase="col.type ==='activity_daily' ? col.type : col.type ==='text'">
            <input matInput [type]="col.type" [(ngModel)]="element[col.key]" />
          </mat-form-field>
          <mat-form-field *ngSwitchCase="col.type ==='text' ? col.type : ''">
            <input [type]="col.type" matInput [(ngModel)]="element[col.key]" disabled/>
          </mat-form-field>
          <mat-form-field class="text-overflow text-size-4 resizeMatSelect" *ngSwitchCase="'indicator_hour_daily'" ng-disabled="'isEdit'">
            <img width="12" height="12" [src]="selectedLanguage">
            <mat-select [(value)]="selectedLanguage">
              <mat-select-trigger>
                {{selectedLanguage}}
              </mat-select-trigger>
              <mat-option *ngFor="let category of categories" [value]="category.image">
                <img width="12" height="12" [src]="category.image"> {{category.viewValue}}
              </mat-option>
            </mat-select>
          </mat-form-field>
          <mat-form-field class="text-overflow text-size-4 resizeMatSelect" *ngSwitchCase="'indicator_activity_daily'">
            <mat-select [(value)]="selectedActivity">
              <mat-select-trigger>
                <img width="12" height="12" [src]="selectedActivity"> {{selectedActivity}}
              </mat-select-trigger>
              <mat-option *ngFor="let activity of categories" [value]="activity.image">
                <img width="12" height="12" [src]="activity.image"> {{activity.viewValue}}
              </mat-option>
            </mat-select>
          </mat-form-field>
        </div>
      </td>
    </ng-container>
    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
  </table>
  <mat-paginator #paginator [length]="dataSource.filteredData.length" [pageIndex]="0" [pageSize]="5" [pageSizeOptions]="[5, 10, 20]">
  </mat-paginator>
</section>

解决方案

1. 建立数据源与分页器的关联

这是分页不生效的核心原因,必须将MatPaginator实例绑定到MatTableDataSource的paginator属性:

  • 在组件类中添加ViewChild获取分页器引用:
    import { ViewChild } from '@angular/core';
    import { MatPaginator } from '@angular/material/paginator';
    
    // ...
    
    @ViewChild('paginator') paginator!: MatPaginator;
    
  • 在数据加载完成后(或ngAfterViewInit钩子中)绑定分页器:
    ngAfterViewInit() {
      this.dataSource.paginator = this.paginator;
    }
    // 或者在getDataIsSelected的subscribe回调末尾添加:
    this.dataSource.paginator = this.paginator;
    

2. 修正数据长度的获取方式

_filterData是私有属性,不应该直接访问,改用公开的filteredData属性:

console.log('length', this.dataSource.filteredData.length);

3. 优化分页器的length绑定

关联数据源后,分页器会自动同步数据长度,无需手动绑定[length],修改分页器代码:

<mat-paginator #paginator [pageIndex]="0" [pageSize]="5" [pageSizeOptions]="[5, 10, 20]">
</mat-paginator>

4. 验证数据正确性

确认接口返回的res.apidata是有效数组,在subscribe中打印this.request检查数据数量是否符合预期,避免因数据格式错误导致分页异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:15:56