Angular表格汇总行触发ExpressionChangedAfterItHasBeenCheckedError求助
PrimeNG树表格动态汇总行的ExpressionChangedAfterItHasBeenCheckedError问题
需求
为带筛选功能的PrimeNG树表格实现汇总行,要求仅统计当前视图内的数据,汇总结果需随树展开/折叠、筛选操作动态更新。
当前实现方案
- 将
summaryFunction作为元素属性[attr.summaryFunction]绑定到表格单元格,在渲染每行数据时累加计算汇总值 - 在
ngDoCheck钩子中重置summaryMap,避免重复累加(尝试ngOnInit/ngOnViewInit/ngOnChanges均无法正确重置,会导致汇总值重复累加错误)
遇到的问题
功能运行正常,但浏览器针对每列触发三次ExpressionChangedAfterItHasBeenCheckedError错误。
尝试过的无效修复方法
- 更换生命周期钩子:导致汇总值计算错误
- 在
summaryFunction中添加cd.detectChanges():触发无限循环 - 用
setTimeout包裹判断逻辑:触发无限循环 - 用
Promise.resolve().then包裹判断逻辑:触发无限循环
需要解决的问题
- 消除
ExpressionChangedAfterItHasBeenCheckedError错误 - 理解上述常规修复方法引发无限循环的原因
TypeScript代码
export class PrimetreeComponent implements OnInit, DoCheck { sampleData: TreeNode[] = [] columns: any[] = []; summaryMap = new Map(); columnIndex = 0; constructor(private nodeService: NodeService, private cd: ChangeDetectorRef) {} ngOnInit(): void { this.nodeService.getFilesystem().subscribe(data => {this.sampleData = data}); this.columns = [ {field: 'name', header: 'name'}, {field: 'size', header: 'size'}, {field: 'type', header: 'type'}] } ngDoCheck(): void { this.summaryMap = new Map(); } summaryFunction(columnIndex:number, rowData:any){ if(this.summaryMap.has(columnIndex)){ //如果行数据是数字则累加,否则统计行数 if(Number(rowData)){ this.summaryMap.set(columnIndex, this.summaryMap.get(columnIndex)+Number(rowData)); } else { this.summaryMap.set(columnIndex, this.summaryMap.get(columnIndex)+1) } } else { if(Number(rowData)){ this.summaryMap.set(columnIndex, Number(rowData)); } else { this.summaryMap.set(columnIndex, 1) } } } }
HTML模板代码
<p-treeTable #tt [value]="sampleData" [columns]="columns"> <ng-template pTemplate="caption"> <div style="text-align: right"> <span class="p-input-icon-left"> <i class="pi pi-search"></i> <input pInputText type="text" size="50" placeholder="Global Filter" (input)="tt.filterGlobal($any($event.target).value, 'contains')" style="width:auto" /> </span> </div> </ng-template> <ng-template pTemplate="header" let-columns> <tr> <th *ngFor="let col of columns"> {{ col.header }} </th> </tr> <tr> <th *ngFor="let col of columns"> <input pInputText type="text" class="w-full" (input)=" tt.filter($any($event.target).value, col.field, col.filterMatchMode) " /> </th> </tr> </ng-template> <ng-template pTemplate="body" let-rowNode let-rowData="rowData" > <tr> <td *ngFor="let col of columns; let i = index;" [attr.summaryFunction]="summaryFunction(i,rowData[col.field])"> <p-treeTableToggler [rowNode]="rowNode" *ngIf="i == 0" (columnIndex)="i" ></p-treeTableToggler> {{ rowData[col.field] }} </td> </tr> </ng-template> <ng-template pTemplate="emptymessage"> <tr> <td [attr.colspan]="columns.length">No data found.</td> </tr> </ng-template> <ng-template pTemplate="summary"> <tr> <td *ngFor="let col of columns; let i = index;"> {{ col.header }}--sumMap--{{summaryMap.get(i) }} </td> </tr> </ng-template>
内容的提问来源于stack exchange,提问作者Monjoie11
相关产品推荐
相关产品推荐

