在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
相关产品推荐
相关产品推荐

