如何在Angular中动态插入Ignite UI层级网格?
问题:Angular动态插入Ignite UI层级网格遇错误
背景
我参考Ignite UI Angular的层级网格组件,尝试动态插入完整的HTML代码片段,但直接操作DOM和使用innerHTML均无效。于是尝试使用ngx-dynamic-hooks库,用法如下:
<div class="grid__wrapper"> <ngx-dynamic-hooks [content]="grid_html"></ngx-dynamic-hooks> </div>
在TypeScript中定义网格的HTML内容:
export class UsersGridComponent implements OnInit { public years = 10; public localdata: any[]; public col: IgxColumnComponent; public pWidth: string; public nWidth: string; public singers: any[]; data: SafeHtml; constructor(private sanitizer: DomSanitizer) { this.singers = SINGERS; this.localdata = this.singers; this.data = this.sanitizer.sanitize(SecurityContext.HTML, this.grid_html); } ngOnInit(): void {} grid_html: any = `<igx-hierarchical-grid IgxPreventDocumentScroll class="hierarchicalGrid" [data]="localdata" (columnResized)="onResize($event)" [autoGenerate]="false" [height]="'480px'" [width]="'100%'" [rowHeight]="'65px'" #hierarchicalGrid > <igx-column field="Artist" [resizable]="true"></igx-column> <igx-column field="Photo" [resizable]="true" [minWidth]="'115px'"> <ng-template igxCell let-cell="cell"> <div class="cell__inner_2"> <img [src]="cell.value" class="photo" /> </div> </ng-template> </igx-column> <igx-column field="Debut" [resizable]="true" [minWidth]="'88px'" [maxWidth]="'230px'" dataType="number" [formatter]="formatter" ></igx-column> <igx-column field="GrammyNominations" header="Grammy Nominations" [resizable]="true" ></igx-column> <igx-column field="GrammyAwards" header="Grammy Awards" [resizable]="true" ></igx-column> <igx-column field="Sales" header="Album Sales in last {{ this.years }} years" [width]="'230px'" [filterable]="false" > <ng-template igxCell let-val> <igx-sparkline height="40px" width="220px" [dataSource]="val" valueMemberPath="Copies" displayType="Line" lineThickness="2" brush="rgb(255,102,0)" > </igx-sparkline> </ng-template> </igx-column> <igx-row-island [height]="null" [key]="'Albums'" [autoGenerate]="false"> <igx-column field="Album" [resizable]="true"></igx-column> <igx-column field="LaunchDate" header="Launch Date" [resizable]="true" [dataType]="'date'" ></igx-column> <igx-column field="BillboardReview" header="Billboard Review" [resizable]="true" ></igx-column> <igx-column field="USBillboard200" header="US Billboard 200" [resizable]="true" ></igx-column> <igx-row-island [height]="null" [key]="'Songs'" [autoGenerate]="false"> <igx-column field="Number" header="No." [resizable]="true"></igx-column> <igx-column field="Title" [resizable]="true"></igx-column> <igx-column field="Released" dataType="date" [resizable]="true" ></igx-column> <igx-column field="Genre" [resizable]="true"></igx-column> </igx-row-island> </igx-row-island> <igx-row-island [height]="null" [key]="'Tours'" [autoGenerate]="false"> <igx-column field="Tour" [resizable]="true"></igx-column> <igx-column field="StartedOn" header="Started on" [resizable]="true" ></igx-column> <igx-column field="Location" [resizable]="true"></igx-column> <igx-column field="Headliner" [resizable]="true"></igx-column> </igx-row-island> </igx-hierarchical-grid>`; public onResize(event) { this.col = event.column; this.pWidth = event.prevWidth; this.nWidth = event.newWidth; } public formatter = (a) => a; }
已导入必要模块:
const componentParsers: Array<HookParserEntry> = [ { component: IgxHierarchicalGridComponent }, { component: IgxColumnComponent }, { component: IgxRowIslandComponent }, ]; @NgModule({ declarations: [UsersGridComponent], imports: [ BrowserModule, BrowserAnimationsModule, FormsModule, IgxPreventDocumentScrollModule, IgxHierarchicalGridModule, IgxSparklineCoreModule, IgxSparklineModule, DynamicHooksModule.forRoot({ globalParsers: componentParsers }), ], providers: [], bootstrap: [UsersGridComponent], }) export class UsersGridModule {}
当前遇到错误:
请问这种实现方式能否解决问题,还是根本不可行?
问题分析与解决方案
从错误提示来看,核心问题是动态模板中的指令(如igxCell)和子组件(如igx-sparkline)未被ngx-dynamic-hooks正确解析,因为全局解析器仅注册了部分顶层组件,缺少依赖的指令和子组件支持。
具体修复步骤:
- 补充注册缺失的组件与指令
把动态模板中用到的所有Ignite UI组件、指令都添加到componentParsers中,示例:const componentParsers: Array<HookParserEntry> = [ { component: IgxHierarchicalGridComponent }, { component: IgxColumnComponent }, { component: IgxRowIslandComponent }, { component: IgxSparklineComponent }, { directive: IgxCellTemplateDirective }, // 注册单元格模板指令 // 其他用到的指令/组件需逐一补充 ]; - 修正模板插值语法
动态模板中无需使用this关键字,直接访问组件属性即可,修改为:header="Album Sales in last {{ years }} years" - 调整DomSanitizer的使用
ngx-dynamic-hooks会自行处理模板安全,建议移除sanitize步骤,直接传递原始grid_html给[content]属性。 - 确认上下文绑定有效性
组件中的公共属性(如localdata)和方法(如onResize)默认会作为动态模板的上下文,确保这些成员都是公共可访问的。
可行性说明
这种实现方式是可行的,只要确保所有用到的Angular组件、指令都被正确注册到ngx-dynamic-hooks的解析器中,同时模板语法符合库的要求即可。后续若仍有未解析的元素/指令,继续补充对应的注册项即可。
内容的提问来源于stack exchange,提问作者Kęstutis Ramulionis
相关产品推荐
相关产品推荐

