基于API的Mat-Table中Mat-Paginator无法正常工作的问题
修复Mat-Table配套Mat-Paginator不工作的问题
我帮你定位到了问题的核心:你在获取数据后错误地把dataSource从MatTableDataSource实例直接替换成了原始数组,导致分页器无法和数据源建立关联。下面是详细的问题分析和修复方案:
问题分析
- 你一开始初始化了
dataSource = new MatTableDataSource();,这是正确的,但在getProjects()的回调里,执行了this.dataSource = this.projects;——这里projects是从API获取的原始数组,直接替换后dataSource不再是MatTableDataSource实例,自然没有paginator属性,后续ngAfterViewInit里的this.dataSource.paginator = this.paginator;相当于给数组加属性,完全不起作用。 - 手动设置
length是多余的,MatTableDataSource会自动和分页器联动,同步数据长度。
修复后的组件代码
import { DataService } from '../../services/data.service'; import { Component, ViewChild, AfterViewInit, OnInit } from '@angular/core'; import { MatPaginator, MatTableDataSource } from '@angular/material'; @Component({ selector: 'app-projects', templateUrl: './projects.component.html', styleUrls: ['./projects.component.css'], }) export class ProjectsComponent implements OnInit, AfterViewInit { projects: any; dataSource = new MatTableDataSource(); displayedColumns: any; pageSize: number = 1; pageSizeOptions = [1, 5, 10, 50]; @ViewChild(MatPaginator) paginator: MatPaginator; constructor(private dataService: DataService) { } ngOnInit() { console.log("Retrieving projects"); this.getProjects().then(projects => { console.log("Projects retrieved", projects); this.projects = projects; // 关键修复:不要替换dataSource实例,而是设置它的data属性 this.dataSource.data = projects; console.log(this.dataSource); this.displayedColumns = [ 'prj_id', 'title', 'priority_id' ]; // 移除手动设置length的代码,MatTableDataSource会自动处理 }).catch(function (data) { console.log("Rejected", data); }); } ngAfterViewInit() { // 确保dataSource是MatTableDataSource实例,关联分页器 this.dataSource.paginator = this.paginator; } getProjects() { let promise = new Promise((resolve, reject) => { this.dataService.getProjects().subscribe( projects => { resolve(projects); }, error => { console.log("error retrieving projects"); reject("error retrieving projects"); } ) }); return promise; } } export interface Projects { prj_id: string; title: string; priority_id: number; }
修复后的HTML视图代码
(主要移除了手动绑定的[length],因为现在分页器会从dataSource自动获取长度)
<div fxLayout="column" fxLayoutAlign="center center" > <button mat-raised-button color="primary" ><mat-icon>add</mat-icon>Project</button> </div> <div fxLayout="row" fxLayoutWrap="wrap"> <div fxFlex.gt-sm="100" fxFlex.gt-xs="100" fxFlex="100"> <mat-card> <mat-card-content> <mat-card-title backgroundColor="primary">Projects</mat-card-title> <div class="table-rasponsive"> <mat-table #table [dataSource]="dataSource"> <!-- Position Column --> <ng-container matColumnDef="prj_id"> <mat-header-cell *matHeaderCellDef> ID </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.prj_id}} </mat-cell> </ng-container> <!-- Name Column --> <ng-container matColumnDef="title"> <mat-header-cell *matHeaderCellDef> TITLE </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.title}} </mat-cell> </ng-container> <!-- Name Column --> <ng-container matColumnDef="priority_id"> <mat-header-cell *matHeaderCellDef> PRIORITY </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.priority_id}} </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> </mat-table> <mat-paginator #paginator [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions"> </mat-paginator> </div> </mat-card-content> </mat-card> </div> </div>
额外说明
MatTableDataSource是Angular Material提供的专门用于表格的数据源包装类,它内置了分页、排序、过滤的支持,必须保持它的实例身份,不能直接用数组替换。- 当你设置
dataSource.data = projects后,MatTableDataSource会自动处理数据的变化,分页器关联后就能正常工作了。
内容的提问来源于stack exchange,提问作者Kerby82
相关产品推荐
相关产品推荐

