Angular内容投影仅最后一处生效,复用表格时单元格内容丢失如何解决
问题根因
Angular 中ng-content对应的DOM节点是全局唯一的,当你多次使用同一个CustomTableComponent的TemplateRef进行渲染时,之前渲染实例中已经挂载的投影DOM节点会被移动到最新的渲染位置,因此只有最后一个ParentComponent实例能看到完整的单元格内容,前面的实例单元格都会变成空。
解决方案
方案1:替换ng-content为输入型模板(改动最小,兼容现有组件结构)
修改RowComponent,将原本用ng-content接收的内容改为接收外部传入的TemplateRef,避免DOM节点唯一的问题:
export class RowComponent { @Input() col1Tpl: TemplateRef<any>; @Input() col2Tpl: TemplateRef<any>; @ViewChild(TemplateRef, { static: true }) template: TemplateRef<any>; }
调整RowComponent模板:
<ng-template> <td><ng-container *ngTemplateOutlet="col1Tpl"></ng-container></td> <td><ng-container *ngTemplateOutlet="col2Tpl"></ng-container></td> </ng-template>
调用方写法调整为用ng-template定义单元格内容传入:
<custom-table #customTable> <row [col1Tpl]="row1Col1" [col2Tpl]="row1Col2"></row> <ng-template #row1Col1>Col1Row1</ng-template> <ng-template #row1Col2>Col2Row1</ng-template> <row [col1Tpl]="row2Col1" [col2Tpl]="row2Col2"></row> <ng-template #row2Col1>Col1Row2</ng-template> <ng-template #row2Col2>Col2Row2</ng-template> </custom-table> <parent [table]="customTable"></parent> <parent [table]="customTable"></parent> <parent [table]="customTable"></parent>
方案2:数据驱动渲染(性能最优,适合固定结构表格)
如果表格列结构固定,直接将行数据作为输入传入组件,完全弃用内容投影,从根源避免该问题:
修改CustomTableComponent新增输入属性:
export class CustomTableComponent implements AfterContentInit { @ViewChild(TemplateRef, { static: true }) template: TemplateRef<any>; // 新增输入 @Input() columns: {key: string, title: string}[]; @Input() tableData: Record<string, any>[]; }
调整CustomTableComponent模板:
<ng-template> <table> <thead> <tr> <td *ngFor="let col of columns">{{col.title}}</td> </tr> </thead> <tbody> <tr *ngFor="let row of tableData"> <td *ngFor="let col of columns">{{row[col.key]}}</td> </tr> </tbody> </table> </ng-template>
调用方直接传递数据即可:
<custom-table #customTable [columns]="[ {key: 'col1', title: 'Col1'}, {key: 'col2', title: 'Col2'} ]" [tableData]="[ {col1: 'Col1Row1', col2: 'Col2Row1'}, {col1: 'Col1Row2', col2: 'Col2Row2'} ]" ></custom-table> <parent [table]="customTable"></parent> <parent [table]="customTable"></parent> <parent [table]="customTable"></parent>
内容的提问来源于stack exchange,提问作者Liviu Boboia
相关产品推荐
相关产品推荐

