Angular Material分页失效求助:动态表格分页不生效
Angular Material分页器无法生效问题排查与解决
我正在跟随Muhi Masri的教程《Load, Add, Update and Delete Table Rows using API Services》(强烈推荐该教程)制作可编辑动态表格。通过日期过滤后使用MatTableDataSource渲染表格数据,但添加Angular Material分页器后完全无法生效,按官方文档操作仍无效果,this.dataSource._filterData.length返回值始终为1。
相关代码
TypeScript代码
// 列配置 displayedColumns: string[] = ActivityColumns.map((col) => col.key); columnsSchema: any = ActivityColumns; // 数据源 dataSource = new MatTableDataSource<ApidatumDisplay>(); request: ApidatumDisplay[] = [] getDataIsSelected() { let dailydata = { startDate: this.selected.startDate.format("YYYY-MM-DD"), endDate: this.selected.endDate.format("YYYY-MM-DD") } const validStartSelected = dailydata.startDate; this.editDateisNow = validStartSelected === dayjs().format("YYYY-MM-DD"); // 请求接口 this.reportesService.getDailyTracking(dailydata).pipe(takeUntil(this.unsubscribe$)).subscribe((res) => { this.request = res.apidata; this.dataSource.data = this.request; console.log('length', this.dataSource._filterData.length); // 返回1 this.averageTotal = res.adding_total_activity this.hourTimeTotal = this.convert(res.adding_total_hours); this.expectedBudget = 192 * 22; this.isReload = false; }); }
HTML代码
<!--Table of content--> <section class="rounded mt-2 border overflow-hidden"> <table mat-table [dataSource]="dataSource"> <ng-container class="text-uppercase border" [matColumnDef]="col.key" *ngFor="let col of columnsSchema"> <th class="vertical-align-middle" mat-header-cell *matHeaderCellDef> <div class="d-flex align-items-center"> <div class=" text-size-4 text-overflow mr-1"> {{ col.label }} </div> </div> </th> <td class=" text-size-3 font-weight-regular " mat-cell *matCellDef="let element"> <div class="text-overflow text-size-4 mr-1" [ngSwitch]="col.type" *ngIf="!element.isEdit"> <div class="btn-edit" *ngSwitchCase="'isEdit'"> <button mat-button (click)="element.isEdit=!element.isEdit"> Editar </button> </div> <span *ngSwitchCase="'text'"> {{ element[col.key] }} </span> <span *ngSwitchDefault> {{ element[col.key] }} </span> <div class="text-overflow text-size-4" *ngSwitchCase="'indicator_hour_daily'"> <img style="height: 12px;" src="https://ymlabqgbnnbvyybcyqjn.supabase.co/storage/v1/object/public/assets-ui/icons/status-{{element.indicator_hour_daily}}.svg" alt="status"> </div> <div class="text-overflow text-size-4" *ngSwitchCase="'indicator_activity_daily'"> <img style="height: 12px;" src="https://ymlabqgbnnbvyybcyqjn.supabase.co/storage/v1/object/public/assets-ui/icons/status-{{element.indicator_activity_daily}}.svg" alt="status"> </div> </div> <div class="text-overflow text-size-4" [ngSwitch]="col.type" *ngIf="element.isEdit"> <div *ngSwitchCase="'isSelected'"></div> <div class="btn-edit" *ngSwitchCase="'isEdit'"> <button mat-button (click)="editRow(element)">Hecho</button> <button mat-button (click)="cancelEditActivity(element)">Cancelar</button> </div> <mat-form-field *ngSwitchCase="col.type ==='activity_daily' ? col.type : col.type ==='text'"> <input matInput [type]="col.type" [(ngModel)]="element[col.key]" /> </mat-form-field> <mat-form-field *ngSwitchCase="col.type ==='text' ? col.type : ''"> <input [type]="col.type" matInput [(ngModel)]="element[col.key]" disabled/> </mat-form-field> <mat-form-field class="text-overflow text-size-4 resizeMatSelect" *ngSwitchCase="'indicator_hour_daily'" ng-disabled="'isEdit'"> <img width="12" height="12" [src]="selectedLanguage"> <mat-select [(value)]="selectedLanguage"> <mat-select-trigger> {{selectedLanguage}} </mat-select-trigger> <mat-option *ngFor="let category of categories" [value]="category.image"> <img width="12" height="12" [src]="category.image"> {{category.viewValue}} </mat-option> </mat-select> </mat-form-field> <mat-form-field class="text-overflow text-size-4 resizeMatSelect" *ngSwitchCase="'indicator_activity_daily'"> <mat-select [(value)]="selectedActivity"> <mat-select-trigger> <img width="12" height="12" [src]="selectedActivity"> {{selectedActivity}} </mat-select-trigger> <mat-option *ngFor="let activity of categories" [value]="activity.image"> <img width="12" height="12" [src]="activity.image"> {{activity.viewValue}} </mat-option> </mat-select> </mat-form-field> </div> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr> </table> <mat-paginator #paginator [length]="dataSource.filteredData.length" [pageIndex]="0" [pageSize]="5" [pageSizeOptions]="[5, 10, 20]"> </mat-paginator> </section>
解决方案
1. 建立数据源与分页器的关联
这是分页不生效的核心原因,必须将MatPaginator实例绑定到MatTableDataSource的paginator属性:
- 在组件类中添加ViewChild获取分页器引用:
import { ViewChild } from '@angular/core'; import { MatPaginator } from '@angular/material/paginator'; // ... @ViewChild('paginator') paginator!: MatPaginator; - 在数据加载完成后(或
ngAfterViewInit钩子中)绑定分页器:ngAfterViewInit() { this.dataSource.paginator = this.paginator; } // 或者在getDataIsSelected的subscribe回调末尾添加: this.dataSource.paginator = this.paginator;
2. 修正数据长度的获取方式
_filterData是私有属性,不应该直接访问,改用公开的filteredData属性:
console.log('length', this.dataSource.filteredData.length);
3. 优化分页器的length绑定
关联数据源后,分页器会自动同步数据长度,无需手动绑定[length],修改分页器代码:
<mat-paginator #paginator [pageIndex]="0" [pageSize]="5" [pageSizeOptions]="[5, 10, 20]"> </mat-paginator>
4. 验证数据正确性
确认接口返回的res.apidata是有效数组,在subscribe中打印this.request检查数据数量是否符合预期,避免因数据格式错误导致分页异常。
内容的提问来源于stack exchange,提问作者Izlia
相关产品推荐
相关产品推荐

