使用Angular迭代<tr>实现可折叠表格时递归组件报错如何解决
你遇到的报错是因为将属性型组件 [app-table-row] 绑定在了 <ng-container> 上。<ng-container> 是 Angular 提供的虚拟容器,不会在真实 DOM 中生成任何节点,组件内部渲染的 <tr> 元素找不到可挂载的真实父 DOM 节点,因此触发了 appendChild 相关的 DOM 异常。
修复方案
推荐使用 ng-template + ngTemplateOutlet 实现递归逻辑,无需调整现有组件的定义和上层绑定逻辑:
- 替换
app-table-row组件的模板代码如下:
<ng-container *ngFor="let row of rows"> <!-- 渲染当前层级行 --> <tr> <td *ngFor="let cell of row.cells"> {{cell}} </td> </tr> <!-- 存在子行时递归渲染 --> <ng-container *ngIf="row.childRows && row.childRows.length"> <ng-container *ngTemplateOutlet="childRowsTpl; context: { $implicit: row.childRows }"></ng-container> </ng-container> </ng-container> <!-- 递归子行模板 --> <ng-template #childRowsTpl let-childRows> <ng-container *ngFor="let row of childRows"> <tr> <td *ngFor="let cell of row.cells"> {{cell}} </td> </tr> <ng-container *ngIf="row.childRows && row.childRows.length"> <ng-container *ngTemplateOutlet="childRowsTpl; context: { $implicit: row.childRows }"></ng-container> </ng-container> </ng-container> </ng-template>
- 原有
<tbody app-table-row [table]="table" [rows]="table.rows">的绑定逻辑保持不变即可。
后续要实现折叠展开功能时,只需要给每行数据新增一个isExpand状态变量,点击父行时切换该状态,在子行渲染的ng-container上加上*ngIf="row.isExpand"的判断即可。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

