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

Angular中Mat Pagination与Mat Sort功能失效求助

解决Angular Mat Pagination与Mat Sort失效问题(分页显示“0 of 0”、排序无响应)

在使用Angular Material的Mat Pagination和Mat Sort组件时,出现两个核心问题:

  • 分页组件始终显示“0 of 0”
  • 表头的排序功能完全无法工作

API返回的示例数据如下:

{
    "body": {
        "httpstatuscode": 200,
        "AppData": [
            {
                "disk": "0",
                "load": "0.25",
                "sno": 1,
                "instances": "Instance1",
                "cpu": "0",
                "ram": "0.25"
            },
            {
                "disk": "0",
                "load": "0",
                "sno": 2,
                "instances": "Instance2",
                "cpu": "0",
                "ram": "0"
            }
        ],
        "opStatusCode": 2000,
        "type": "SUCCESS",
        "message": "DATA RECEIVED SUCCESSFULLY"
    }
}

组件模板代码(component.html)

<div>
  <table style="position: sticky; overflow: scroll;"
    mat-table
    matSort
    [dataSource]="dataSource">
    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->
    <ng-container matColumnDef="sno">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>SNO</th>
      <td mat-cell *matCellDef="let element">{{ element.sno }}</td>
    </ng-container>
    <ng-container matColumnDef="instances">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Instances</th>
      <td mat-cell *matCellDef="let element">{{ element.instances }}</td>
    </ng-container>
    <ng-container matColumnDef="cpu">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>CPU %</th>
      <td mat-cell *matCellDef="let element">{{ element.cpu }}</td>
    </ng-container>
    <ng-container matColumnDef="ram">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>RAM %</th>
      <td mat-cell *matCellDef="let element">{{ element.ram }}</td>
    </ng-container>
    <ng-container matColumnDef="load">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Load %</th>
      <td mat-cell *matCellDef="let element">{{ element.load }}</td>
    </ng-container>
    <ng-container matColumnDef="disk">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Disk %</th>
      <td mat-cell *matCellDef="let element">{{ element.disk }}</td>
    </ng-container>
    <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
    <tr (click)="fetchProxyData(row.instances)" mat-row *matRowDef="let row; let e = index; columns: displayedColumns;"></tr>
    <tr class="mat-row" *matNoDataRow>
      <td class="mat-cell" colspan="4">
        Data not available.
      </td>
    </tr>
  </table>
  <mat-paginator  #paginator
    [pageSizeOptions]="[5, 10, 25, 100, 150, 200]"
    aria-label="Select page of users" class="mat-paginator-sticky"
  ></mat-paginator>
</div>

组件逻辑代码(component.ts,核心部分)

export interface tableData {
  sno: number;
  instances: string;
  cpu: number;
  ram: number;
  load: number;
  disk: number;
}

dataForTable: tableData[] = []; 
cpuData=[]; ramData=[]; loadData=[]; diskData=[];
displayedColumns: string[] = ['sno', 'instances', 'cpu', 'ram', 'load', 'disk'];
dataSource = new MatTableDataSource(this.dataForTable);

@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;

constructor(private httpclient: HttpClient, private httpService: HttpService) {}

ngAfterViewInit() {
   this.dataSource.paginator = this.paginator;
   this.dataSource.sort = this.sort; 
}

ngOnInit(): void {
   this.fetchData(); 
}

fetchData() {
  this.httpService.getData(request).subscribe((response: any) => {
    const responseString: string = JSON.stringify(response);
    try {
      const jsonObj = JSON.parse(responseString);
      const jsonBody = jsonObj['body'];
      const appData = jsonBody['AppData'];
      this.dataForTable = appData as tableData[];
      this.dataSource=new MatTableDataSource(this.dataForTable);
    } catch (e: any) {
      console.log('Error in parsing json ' + e.message);
    }
    return response;
  });
}

问题根源分析

问题出在fetchData方法中:每次获取数据后重新创建了MatTableDataSource实例,而之前在ngAfterViewInit中绑定的paginator和sort只关联了最初的数据源实例,新实例丢失了这些绑定关系,导致分页组件无法识别数据总量、排序功能无法触发。

另外还有一个隐藏问题:API返回的cpu、ram、load、disk字段是字符串类型,但接口tableData定义为number类型,直接强制转换会导致排序逻辑异常(字符串排序和数值排序规则不同)。

解决方案

  1. 不要重新创建MatTableDataSource,直接更新现有实例的data属性
  2. 将API返回的字符串类型数值转换为number类型,确保排序逻辑正常
  3. 移除冗余的JSON.stringify和JSON.parse操作(HttpClient已自动解析响应为JSON对象)

修改后的fetchData方法代码:

fetchData() {
  this.httpService.getData(request).subscribe((response: any) => {
    try {
      const appData = response.body.AppData;
      // 转换数据类型,确保数值字段为number类型
      this.dataForTable = appData.map(item => ({
        ...item,
        cpu: Number(item.cpu),
        ram: Number(item.ram),
        load: Number(item.load),
        disk: Number(item.disk),
        sno: Number(item.sno) // 虽然API返回的是数字,但统一转换更安全
      })) as tableData[];
      // 直接更新数据源的data属性,保留已绑定的paginator和sort
      this.dataSource.data = this.dataForTable;
    } catch (e: any) {
      console.log('Error in processing data ' + e.message);
    }
  });
}

额外注意事项

  • 确保MatPaginatorModule和MatSortModule已在你的Angular模块中导入
  • 如果分页仍有问题,可以在更新dataSource.data后手动触发分页初始化(一般不需要,但若有异步延迟可尝试):
    setTimeout(() => {
      this.dataSource.paginator = this.paginator;
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 12:54:51