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

Angular中如何基于分页页面对表格数据进行局部排序?

实现Angular Material表格当前页局部排序

默认的MatTable排序会对整个数据集排序后再分页,要实现仅对当前页数据排序,需要重写MatTableDataSource的sortData方法,只针对当前分页的切片数据进行排序操作,具体修改如下:

步骤1:修正原代码错误并添加自定义排序逻辑

先修复原代码里的拼写错误(比如ngAfterViewInt→ngAfterViewInit、Objects→Object、dispalyedColumns→displayedColumns),然后重写sortData方法:

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, Sort } from '@angular/material/sort';

// 辅助排序函数,和Angular默认实现一致
function compare(a: number | string, b: number | string, isAsc: boolean) {
  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}

export class FootballerComponent implements OnInit {
  // 原始完整数据
  originalData = [
    {"name": "Cristiano Ronaldo", "age" : "37"},
    {"name": "Neymar", "age" : "29"},
    {"name": "Messi", "age" : "34"},
    {"name": "KDB", "age" : "31"},
    {"name": "Aguero", "age" : "29"},
    {"name": "Suarez", "age" : "32"},
    {"name": "Mbappe", "age" : "17"}
  ];

  displayedColumns: string[] = Object.keys(this.originalData[0]);
  dataSource = new MatTableDataSource(this.originalData);

  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort, {static: false}) sort!: MatSort;

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

    // 重写sortData方法,实现当前页局部排序
    this.dataSource.sortData = (data: any[], sort: Sort) => {
      if (!sort.active || sort.direction === '') {
        return data;
      }

      // 计算当前页的起始/结束索引
      const startIdx = this.paginator.pageIndex * this.paginator.pageSize;
      const endIdx = startIdx + this.paginator.pageSize;

      // 截取当前页数据并排序
      const currentPageData = data.slice(startIdx, endIdx);
      const sortedCurrentPage = currentPageData.sort((a, b) => {
        const isAsc = sort.direction === 'asc';
        switch (sort.active) {
          case 'name': return compare(a.name, b.name, isAsc);
          case 'age': return compare(+a.age, +b.age, isAsc); // age转数字再比较
          default: return 0;
        }
      });

      // 拼接排序后的当前页与其他页数据,返回新数据集
      return [
        ...data.slice(0, startIdx),
        ...sortedCurrentPage,
        ...data.slice(endIdx)
      ];
    };
  }

  constructor() {}
  ngOnInit(): void {}
}

步骤2:修正HTML代码错误

修复HTML里的属性拼写和语法错误:

<mat-paginator #paginator [pageSize]="3" [pageSizeOptions]="[2,3,4,5]" showFirstLastButtons></mat-paginator>

<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
  <ng-container [matColumnDef]="column" *ngFor="let column of displayedColumns">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> {{ column }} </th>
    <td mat-cell *matCellDef="let emp"> {{ emp[column] }} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>

关键逻辑说明

  1. 重写sortData:默认的sortData会对整个数据集排序,这里我们只截取当前分页对应的切片数据进行排序,再将排序后的切片放回原数据集的对应位置。
  2. 分页索引计算:通过paginator.pageIndex和paginator.pageSize算出当前页数据的起始/结束位置,确保只处理当前可见的行。
  3. 类型转换:排序age字段时,将字符串转为数字,避免字典序排序错误(比如"17"和"37"的排序问题)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:16:09