我正在尝试从JSON动态创建Angular4组件,这些组件可能有这样的结构(伪):
-TabContainerComponent
-- TabComponent
--- TextInputComponent
--- ComboboxComponent
-- TabComponent
--- WhateverComponent
所以总有一个根组件,如果它提供了翻译(意味着它的模板中有<ng-content>
),它就有一个n个子组合。
在模板中,此JSON将转换为类似
的内容<tab-container>
<tab>
<text-input></text-input>
<combobox></combobox>
</tab>
<tab>
<whatever></whatever>
</tab>
</tab-container>
现在我正在尝试使用viewContainer.createComponent
在代码中创建此DOM。我基本上遍历反序列化的JSON中的每个节点并将其传递给此函数:
// T is for example TabComponent or WhateverComponent
const childComponent = this.componentFactoryResolver.resolveComponentFactory(<Type<{}>>T);
const result: ComponentRef<{}> = parentNode.createComponent(childComponent);
顶级parentNode
是我模板中的静态div和所有这种创造魔法的根节点。
现在,您可以想象,组件通常需要访问@ViewChildren
中的AfterContentInit
。例如,TabContainer可能会尝试自动选择第一个选项卡,如下所示:
@ContentChildren(TabComponent)
public tabs: QueryList<TabComponent>;
public ngAfterContentInit() {
const activeTabs = this.tabs.filter((tab) => tab.isActive);
if (activeTabs.length === 0) {
this.selectTab(this.tabs.first);
}
}
问题是:一旦我调用viewContainer.createComponent
,创建的组件就会遍历其所有生命周期事件 - 这是在其子项被反序列化和创建之前。另一方面,我不能从底部到顶部遍历我的JSON并从最低的子节点开始,因为我需要在尚不存在的parentNode上调用createComponent
。
整个翻译机制顺便说一下。我可以在DOM中看到所有想要的节点,但总是无法访问我的ViewChildren。
你知道如何解决这个问题吗?我可以创建组件而不实际“将它们变为现实”吗?我应该使用另一个生命周期钩子,还是我做错了?