Angular Material mat-table循环仅显示一条数据的解决方案求助
Angular Material mat-table仅显示一条数据的排查与解决
我使用Angular Material的mat-table在循环内展示记录,接口返回两条数据,但当前代码仅显示一条。以下是返回数组、HTML代码及TS代码,请求排查并给出解决方案。表格仅显示一条数据。
返回数组
[ { "unitTypeSizeConcat": [ "HJHJ", "ABC" ], "list": [ { "id": "6665c40f93ff924ef96e05de", "subscriberId": "6331733aa38f414a418ab3fc", "locationId": "64f85dff2f4280212657f7e7", "description": "test", "unitRateType": "Rented Unit Below Board Rate", "unitRateTypeId": 1, "rateChangeType": "Rotating Fixed Amount", "value": "5", "effectiveDate": "01/01/2024", "recurringPeriod": "5", "noticeDays": "5", "applyBySize": true, "applyByUnit": false, "applyByUnitSizeCode": "6662dc6325bec37c0cedf0d9", "applyByUnits": [], "applyByUnitId": "MongoObjectId(id=null)", "applyByUnitName": null, "revisionHistory": 0, "unitTypeSizeConcat": "HJHJ;ABC", "lastRateChangeDate": null, "lastRateChangeAmount": null, "noticeDate": null }, { "id": "66f4f05eb5c2b8424c431fc7", "subscriberId": "6331733aa38f414a418ab3fc", "locationId": "64f85dff2f4280212657f7e7", "description": "ghgh", "unitRateType": "Rented Unit Below Board Rate", "unitRateTypeId": 1, "rateChangeType": "Rotating Fixed Amount", "value": "2", "effectiveDate": null, "recurringPeriod": "2", "noticeDays": "2", "applyBySize": true, "applyByUnit": false, "applyByUnitSizeCode": "6662dc6325bec37c0cedf0d9", "applyByUnits": [ "666ab7306ac32055804a25b5", "666bdba59783af20ce55b5ff", "6679aba38a764d4b153d6d8d", "667aac1bbcb1e01439e96368", "667d1b6d0306513a6c75ed30", "66c5d8e97cf2c6598e91c134" ], "applyByUnitId": "000000000000000000000000", "applyByUnitName": null, "revisionHistory": 0, "unitTypeSizeConcat": "HJHJ;ABC", "lastRateChangeDate": null, "lastRateChangeAmount": null, "noticeDate": null } ] } ]
HTML代码
<div *ngFor="let rc of filteredSizeCode" class="table-responsive table-content"> <h3 class="text-primary mt-1 mb-3">Unit Type : {{rc.unitTypeSizeConcat[0]}}</h3> <table mat-table [dataSource]="datasource" matSort class="mat-elevation-z8" matSortDisableClear> <ng-container matColumnDef="unitRateType"> <th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Unit Rate Filter</th> <td mat-cell *matCellDef="let row; let i=index">{{row.list[i].unitRateType}}</td> </ng-container> <ng-container matColumnDef="rateChangeType"> <th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Rate Change Type</th> <td mat-cell *matCellDef="let row; let i=index">{{row.list[i].rateChangeType}}</td> </ng-container> <ng-container matColumnDef="effectiveDate"> <th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Effective Date</th> <td mat-cell *matCellDef="let row; let i=index">{{row.list[i].effectiveDate | date: 'MM-dd-yyyy'}}</td> </ng-container> <ng-container matColumnDef="noticeDays"> <th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Notice Days</th> <td mat-cell *matCellDef="let row; let i=index ">{{row.list[i].noticeDays}}</td> </ng-container> <ng-container matColumnDef="value"> <th style="padding-left:28px;" mat-header-cell *matHeaderCellDef mat-sort-header>Value</th> <td mat-cell *matCellDef="let row; let i=index">{{row.list[i].rateChangeType == 'Rotating Fixed Amount' || row.list[i].rateChangeType == 'One Time Only Fixed Amount'?'$':null }} {{row.list[i].value}}{{row.list[i].rateChangeType == 'Rotating Fixed Percentage' || row.list[i].rateChangeType == 'One Time Only Fixed Percentage'?'%':null}} </td> </ng-container> <ng-container matColumnDef="recurringPeriod"> <th style="padding-left:28px;" mat-header-cell *matHeaderCellDef mat-sort-header>Recurring Period</th> <td mat-cell *matCellDef="let row; let i=index">{{row.list[i].recurringPeriod?row.list[i].recurringPeriod:null}}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> </div>
TS代码
displayedColumns = [ 'unitRateType', 'rateChangeType', 'effectiveDate', 'noticeDays', 'value', 'recurringPeriod', ]; datasource = new MatTableDataSource([]); ngOnInit() { this.datasource.data = this.filteredSizeCode; }
问题根源
- 数据源绑定错误:
datasource绑定的是filteredSizeCode数组,而该数组仅包含1个对象(真正要展示的两条数据在对象的list属性里),因此mat-table只会渲染一行。 - 单元格取值逻辑错误:用
row.list[i]取值时,i是表格行的索引,当表格只有一行时i=0,只能取到list[0]的数据,第二条数据无法被渲染。
解决方案
1. 修正数据源绑定
将表格数据源改为当前循环项的rc.list,让每个表格对应自己的目标数据数组:
<table mat-table [dataSource]="rc.list" matSort class="mat-elevation-z8" matSortDisableClear>
2. 修正单元格取值逻辑
直接通过row访问属性,此时row就是list里的单个数据项,无需再通过list[i]取值:
<!-- 示例:修正unitRateType列 --> <td mat-cell *matCellDef="let row">{{row.unitRateType}}</td>
完整修正后的HTML代码
<div *ngFor="let rc of filteredSizeCode" class="table-responsive table-content"> <h3 class="text-primary mt-1 mb-3">Unit Type : {{rc.unitTypeSizeConcat[0]}}</h3> <table mat-table [dataSource]="rc.list" matSort class="mat-elevation-z8" matSortDisableClear> <ng-container matColumnDef="unitRateType"> <th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Unit Rate Filter</th> <td mat-cell *matCellDef="let row">{{row.unitRateType}}</td> </ng-container> <ng-container matColumnDef="rateChangeType"> <th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Rate Change Type</th> <td mat-cell *matCellDef="let row">{{row.rateChangeType}}</td> </ng-container> <ng-container matColumnDef="effectiveDate"> <th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Effective Date</th> <td mat-cell *matCellDef="let row">{{row.effectiveDate | date: 'MM-dd-yyyy'}}</td> </ng-container> <ng-container matColumnDef="noticeDays"> <th class="centered-sorted-header" mat-header-cell *matHeaderCellDef mat-sort-header>Notice Days</th> <td mat-cell *matCellDef="let row">{{row.noticeDays}}</td> </ng-container> <ng-container matColumnDef="value"> <th style="padding-left:28px;" mat-header-cell *matHeaderCellDef mat-sort-header>Value</th> <td mat-cell *matCellDef="let row"> {{row.rateChangeType == 'Rotating Fixed Amount' || row.rateChangeType == 'One Time Only Fixed Amount' ? '$' : null }} {{row.value}}{{row.rateChangeType == 'Rotating Fixed Percentage' || row.rateChangeType == 'One Time Only Fixed Percentage' ? '%' : null}} </td> </ng-container> <ng-container matColumnDef="recurringPeriod"> <th style="padding-left:28px;" mat-header-cell *matHeaderCellDef mat-sort-header>Recurring Period</th> <td mat-cell *matCellDef="let row">{{row.recurringPeriod ? row.recurringPeriod : null}}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> </div>
修正后的TS代码(可选优化)
由于不再使用全局datasource变量,可直接移除:
displayedColumns = [ 'unitRateType', 'rateChangeType', 'effectiveDate', 'noticeDays', 'value', 'recurringPeriod', ]; ngOnInit() { // 保留filteredSizeCode的赋值逻辑(原代码未展示,需确保已正确获取接口数据) }
内容的提问来源于stack exchange,提问作者Asna Khan
相关产品推荐
相关产品推荐

