如何为嵌套在mat-table中的动态内部数据源实现分页?
嵌套Mat-Table实现内层分页的解决方案
你的问题核心在于内层表格直接绑定了原始数组而非MatTableDataSource,加上循环生成的多个分页器无法通过单个@ViewChild获取,导致分页绑定失效。下面是具体的修复步骤:
第一步:修改TS逻辑
- 给外层数据的每个元素添加
usersDataSource属性,用来存储封装后的MatTableDataSource:
import { MatTableDataSource, MatPaginator } from '@angular/material'; import { ViewChildren, QueryList } from '@angular/core'; // 类内定义 @ViewChildren('innerPaginator') innerPaginators: QueryList<MatPaginator>; adminsList: any[]; // 你的外层数据源 // 获取用户数据后处理 this.userService.getUserInfo().subscribe((res: userData) => { // 假设res是外层的adminsList数据,每个元素包含users数组 this.adminsList = res.map(item => ({ ...item, usersDataSource: new MatTableDataSource(item.users) // 把users封装成MatTableDataSource })); // 数据加载完成后,关联分页器和数据源 this.innerPaginators.changes.subscribe(() => { this.adminsList.forEach((element, index) => { const paginator = this.innerPaginators.toArray()[index]; if (paginator) { element.usersDataSource.paginator = paginator; } }); }); });
- 移除原来错误的
innerDataSourceObject相关代码,现在每个外层元素都有独立的数据源实例。
第二步:修改HTML模板
- 内层表格的数据源改为绑定封装后的
element.usersDataSource:
<ng-container *ngFor="let el of adminsList"> <table mat-table [dataSource]="myDataSource" multiTemplateDataRows ...> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef> <div>{{el['version'] }}</div> </th> <td mat-cell *matCellDef="let element;"> <!-- 绑定封装后的数据源 --> <table mat-table [dataSource]="element.usersDataSource"> <ng-container matColumnDef="{{innerColumn}}" *ngFor="let innerColumn of columnsToDisplay"> <th mat-header-cell *matHeaderCellDef> {{innerColumn }} </th> <td mat-cell *matCellDef="let innerElement"> {{innerElement[innerColumn]}} </td> </ng-container> <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr> <tr mat-row *matRowDef="let row; columns: columnsToDisplay"></tr> </table> <!-- 保留分页器标记 --> <mat-paginator [pageSize]="5" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons="true" #innerPaginator> </mat-paginator> </td> </ng-container> <!-- 其他外层表格代码不变 --> <ng-container matColumnDef="deployedVersion"> <th mat-header-cell *matHeaderCellDef style="display: none"></th> <td mat-cell *matCellDef="let element" style="display: none"></td> </ng-container> <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr> <tr mat-row *matRowDef="let element; columns: columnsToDisplay"></tr> </table> </ng-container>
关键注意点
- 必须把内层的原始数组
element.users封装成MatTableDataSource,只有MatTableDataSource才支持绑定分页器。 - 使用
@ViewChildren代替@ViewChild,因为循环生成了多个内层分页器,单个@ViewChild只能获取第一个实例。 - 在
innerPaginators.changes回调里关联数据源和分页器,确保DOM渲染完成后再绑定,避免分页器未初始化的问题。
内容的提问来源于stack exchange,提问作者k.vincent
相关产品推荐
相关产品推荐

