Angular Mat Table服务端分页异常:分页器无法启用
问题描述
我基于Angular Material Table实现了一个服务端取数的表格组件,数据通过父组件的@Input() properties: any;传入子组件作为数据源。目前要实现服务端分页,已配置(page)="onChangePage($event)"事件,该事件可获取分页参数并传递给父组件调用API,但分页器的翻页箭头处于禁用状态,无法切换到下一页。检查代码后未发现明显问题,希望得到问题排查思路或解决方案。
相关代码
HTML代码
<table (matSortChange)="sortData($event)" mat-table [dataSource]="dataSource" matSort id="table" cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="drop($event)"> <ng-container matColumnDef={{col.matColumnDef}} *ngFor="let col of gridColumns"> <th mat-header-cell *matHeaderCellDef cdkDrag mat-sort-header> {{col.columnHeader}} </th> <td mat-cell *matCellDef="let row"> <span *ngIf="col.columnHeader !== 'Property Name'"> {{(col.value(row) !== 'null')? col.value(row) : '-'}} </span> <span *ngIf="col.columnHeader === 'Property Name'"> {{(col.value(row) !== 'null')? col.value(row) : '-'}} <br> <span class="property-sub-content">{{row.city}}, {{row.state}}</span> </span> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns;"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="getPlaceDetails(row.propertyAccountId)"></tr> </table> </div> <mat-paginator [length]="properties.totalItemCount" [pageSize]="properties.lastItemOnPage" [pageSizeOptions]="[20, 50, 100]" showFirstLastButtons (page)="onChangePage($event)"></mat-paginator>
TS代码片段
dataSource = new MatTableDataSource<any>(); @ViewChild(MatSort) sort: MatSort; @ViewChild(MatPaginator) paginator: MatPaginator; @Input() properties: any; constructor(private iterableDiffers: IterableDiffers, private _route: Router, private _storageService: StorageService) { this.iterableDiffer = iterableDiffers.find([]).create(null); } ngDoCheck() { let changes = this.iterableDiffer.diff(this.properties); if (changes) { let dataSource: any; dataSource = JSON.stringify(this.properties); dataSource = JSON.parse(dataSource); dataSource = dataSource.filter(x => x.propertyAccountId); this.dataSource.data = dataSource; if(this.dataSource.data) { setTimeout(()=>{this.initFreezeTableHeader();},1000); } } } ngAfterViewInit() { this.dataSource.sort = this.sort; this.dataSource.paginator = this.paginator; } sortData(event) { console.log('EVENT' , event) } ngOnInit(): void { const currAcct = this._storageService.getCurrAcct(); this.currentAccountId = JSON.parse(currAcct).accountId; this.accountName = JSON.parse(currAcct).accountName; this.gridColumns = PROPERTIES.GRID_COLUMNS[this.accountName]; this.displayedColumns = this.gridColumns.map(g => g.matColumnDef); } ngOnDestroy(): void { let customDashBoardSelected = document.querySelector('#dashboard-content-container') as HTMLElement | null; customDashBoardSelected.style.height = '100%'; } drop(event: CdkDragDrop<string[]>) { moveItemInArray(this.displayedColumns, event.previousIndex, event.currentIndex); } applyFilter(event: Event) { const filterValue = (event.target as HTMLInputElement).value; this.dataSource.filter = filterValue.trim().toLowerCase(); } getPlaceDetails(propertyAccountId: string) { this._route.navigateByUrl(`/properties/${propertyAccountId}`); } onChangePage(event:any){ this.filterProperties.emit(event) console.log('event' , event) }
properties示例数据(父组件传入的数据源)
{ "firstItemOnPage": 1, "lastItemOnPage": 20, "totalItemCount": 159, "items": [ { "id": 4619, "propertyName": "A Drug Store", "propertyAccountId": "10323202-S", "addressLine1": "3255 VICKSBURG LN N" }, { "id": 9868, "propertyName": "B Drug Store", "propertyAccountId": "23210187-S", "addressLine1": "900 MAIN AVE" } ] }
问题排查与解决方案
- 分页器
pageSize绑定错误:当前[pageSize]="properties.lastItemOnPage"绑定的是当前页最后一条数据的序号(如第一页是20),但pageSize需要的是每页显示的条数。应改为绑定固定值(如20)或从父组件传入专门的pageSize字段,而非lastItemOnPage。 - 禁用MatTableDataSource的客户端分页:服务端分页场景下,不能设置
this.dataSource.paginator = this.paginator;,否则MatTable会自动计算客户端分页状态,与服务端返回的分页信息冲突,导致分页按钮禁用。需删除ngAfterViewInit中的该赋值语句。 - 数据源赋值错误:
ngDoCheck中错误地对整个properties对象执行filter操作(properties是包含分页信息的对象,不是数组),应该取properties.items作为表格数据源:// 替换原ngDoCheck中的数据源赋值逻辑 this.dataSource.data = this.properties.items.filter(x => x.propertyAccountId); - 同步分页器当前页索引:服务端返回新页数据后,需手动同步分页器的
pageIndex(注意是0基索引),比如父组件返回第二页数据时,设置this.paginator.pageIndex = 1;,确保分页器状态与服务端数据匹配。
内容的提问来源于stack exchange,提问作者Tim Launders
相关产品推荐
相关产品推荐

