You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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正确解析,因为全局解析器仅注册了部分顶层组件,缺少依赖的指令和子组件支持。

具体修复步骤:

  1. 补充注册缺失的组件与指令
    把动态模板中用到的所有Ignite UI组件、指令都添加到componentParsers中,示例:
    const componentParsers: Array<HookParserEntry> = [
      { component: IgxHierarchicalGridComponent },
      { component: IgxColumnComponent },
      { component: IgxRowIslandComponent },
      { component: IgxSparklineComponent },
      { directive: IgxCellTemplateDirective }, // 注册单元格模板指令
      // 其他用到的指令/组件需逐一补充
    ];
    
  2. 修正模板插值语法
    动态模板中无需使用this关键字,直接访问组件属性即可,修改为:
    header="Album Sales in last {{ years }} years"
    
  3. 调整DomSanitizer的使用
    ngx-dynamic-hooks会自行处理模板安全,建议移除sanitize步骤,直接传递原始grid_html给[content]属性。
  4. 确认上下文绑定有效性
    组件中的公共属性(如localdata)和方法(如onResize)默认会作为动态模板的上下文,确保这些成员都是公共可访问的。

可行性说明

这种实现方式是可行的,只要确保所有用到的Angular组件、指令都被正确注册到ngx-dynamic-hooks的解析器中,同时模板语法符合库的要求即可。后续若仍有未解析的元素/指令,继续补充对应的注册项即可。

内容的提问来源于stack exchange,提问作者Kęstutis Ramulionis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:04:45