Angular mat-table如何使用Material Paginator及失效问题咨询
问题修复方案
核心问题原因
- 部门表格数据源
dataSource是普通数组类型,未使用MatTableDataSource封装,Angular Material分页器仅支持绑定MatTableDataSource实例 - 分页器赋值时机错误:
ngOnInit阶段视图未渲染完成,@ViewChild获取的paginator实例还未初始化 loadCity方法逻辑顺序错误:异步请求未返回就提前清空了数据源,且参数存在拼写错误- 两个表格共用同一个分页器未做区分,若需要两个表格分别分页需要定义多个分页器实例
代码修正
HTML 修正(可选:两个表格分别配置分页器)
<div> <!-- 部门表格 --> <table mat-table [dataSource]="dataSource" class="mat-elevation-z8 table-left"> <ng-container [matColumnDef]="column" *ngFor="let column of displayedColumns"> <th id="head" mat-header-cell *matHeaderCellDef> {{column}} </th> <ng-container *ngIf="column != 'cities'; else optionsTemplate"> <td mat-cell *matCellDef="let element"> {{element[column]}} </td> </ng-container> <ng-template #optionsTemplate> <td mat-cell *matCellDef="let element" class="action-link"> <button mat-raised-button (click)="loadCity(element.idDepartment)">Cities</button> </td> </ng-template> </ng-container> <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr> <tr mat-row *matRowDef="let row; columns: columnsToDisplay;"></tr> </table> <!-- 部门表格分页器 --> <mat-paginator #depPaginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator> <!-- 城市表格 --> <table mat-table [dataSource]="dataSourceCity" class="mat-elevation-z8"> <ng-container [matColumnDef]="column" *ngFor="let column of displayedColumnsC"> <th id="head" mat-header-cell *matHeaderCellDef> {{column}} </th> <td mat-cell *matCellDef="let element"> {{element[column]}} </td> </ng-container> <tr mat-header-row *matHeaderRowDef="columnsToDisplayC"></tr> <tr mat-row *matRowDef="let row; columns: columnsToDisplayC;"></tr> </table> <!-- 城市表格分页器 --> <mat-paginator #cityPaginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator> </div>
TS 修正
import { Component, OnInit, ViewChild, AfterViewInit} from '@angular/core'; import { MatPaginator } from '@angular/material/paginator'; import { MatTableDataSource } from '@angular/material/table'; import { DepartmentService } from '../../_service/department.service'; import { Department } from 'src/app/_model/department'; @Component({ selector: 'app-search', templateUrl: './search.component.html', styleUrls: ['./search.component.css'], }) export class SearchComponent implements OnInit, AfterViewInit { displayedColumns: string[] = ['idDepartment', 'name', 'cities']; columnsToDisplay: string[] = this.displayedColumns.slice(); depList: Department[] = []; // 改为MatTableDataSource类型 dataSource = new MatTableDataSource<Department>([]); displayedColumnsC: string[] = ['idCity', 'name']; columnsToDisplayC: string[] = this.displayedColumnsC.slice(); cityList: any[] = []; dataSourceCity = new MatTableDataSource<any>([]); // 分别获取两个分页器实例 @ViewChild('depPaginator') depPaginator: MatPaginator; @ViewChild('cityPaginator') cityPaginator: MatPaginator; constructor(private departService: DepartmentService) { } ngOnInit(): void { this.departService.list().subscribe(data => { this.depList = data.map(element => ({ idDepartment: element.idDepartment, name: element.name })); this.dataSource.data = this.depList; // 数据源更新后重新绑定分页器 this.dataSource.paginator = this.depPaginator; }); } ngAfterViewInit(): void { // 视图渲染完成后再绑定分页器 this.dataSource.paginator = this.depPaginator; this.dataSourceCity.paginator = this.cityPaginator; } loadCity(idDepartment): void { // 先清空旧数据 this.cityList = []; this.dataSourceCity.data = []; // 修正参数拼写错误 this.departService.listCities(idDepartment).subscribe(data => { this.cityList = data.map(element => ({ idCity: element.idCity, name: element.name })); this.dataSourceCity.data = this.cityList; // 城市数据源更新后重新绑定分页器 this.dataSourceCity.paginator = this.cityPaginator; }); } }
补充说明
如果只需要给城市表格加分页,不需要部门表格分页,就保留原有一个分页器即可,只需要把部门的dataSource改回普通数组不用封装,同时修正TS中分页器绑定时机、loadCity逻辑顺序和拼写错误即可生效。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

