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

在async ngFor中动态创建组件报错:无法定义NG_ELEMENT_ID

解决方案:TypeError: can't define property "NG_ELEMENT_ID": Function is not extensible

这个错误的核心原因是从NgRx Store获取的TabItem对象被冻结(不可扩展),当Angular框架试图为动态创建的组件添加内部标识NG_ELEMENT_ID时,无法修改不可扩展的对象,从而抛出异常。以下是具体解决步骤:

1. 解除Store返回对象的冻结状态

NgRx默认会开启不可变性检查,或者如果使用了Immer等状态管理工具,状态对象会被自动冻结。你需要在获取tabs数据时,对每个TabItem做浅拷贝,生成可扩展的新对象:

方式一:修改Selector(推荐)

在定义selectTabs选择器时,返回拷贝后的数组和对象:

export const selectTabs = createSelector(
  selectTabManagerState,
  (state) => state.tabs.map(tab => ({ ...tab })) // 浅拷贝每个TabItem,解除冻结
);

方式二:在组件中转换数据流

如果无法修改Selector,可以在组件的Observable管道中处理:

public tabs$: Observable<TabItem[]> = this.tabManagerStore.select(selectTabs).pipe(
  map(tabs => tabs.map(tab => ({ ...tab }))) // 对每个tab对象做浅拷贝
);

2. 验证动态组件创建逻辑

确保TabComponent没有被标记为不可扩展,同时检查createComponent的调用是否正确:

public selectTab(tab: TabItem): void {
    // 可通过console.log(Object.isExtensible(tab))验证对象是否可扩展
    const container = this.containers.get(tab.containerIndex);
    if (!container) return; // 增加空值判断,避免额外错误
    container.clear();
    const componentRef = container.createComponent(TabComponent);
    // 如果需要传递数据,使用componentRef.instance而非直接修改tab对象
    componentRef.instance.tabData = tab;
}

3. 排查Infragistics版本兼容性

如果上述方法无效,检查当前使用的Infragistics Ignite UI for Angular版本是否与你的Angular版本兼容。部分旧版本的igx-tab-item可能在配合async管道和动态组件创建时存在冲突,尝试升级到最新的稳定兼容版本。


内容的提问来源于stack exchange,提问作者DarkCid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 19:46:05