如何动态渲染任意数量的ng-template

时间:2019-11-14 15:40:47

标签: angular

帖子的标题可能不太准确。我正在制作的是选项卡组件,单击选项卡即可更改视图。 目前,我传递给组件的是一组标签标识符,用于呈现标签按钮。

现在我想要的是该组件的ng-content中类似的东西,将其传递给“ n”个模板或视图,例如:

<my-tabs-component [tabs]="['tab1','tab2']">
    <ng-template [view]="'tab1'">
        Tab 1 content
    <ng-template/>
    <ng-template [view]="'tab2'">
        Tab 2 content
    <ng-template/>
</my-tabs-component>

很明显,语法可能是不正确的,我读了一些有关templateOutlet的信息,但我无法达到正确的方法。

为我提供了指向文档,解决方案的链接……欢迎您提供任何帮助。

1 个答案:

答案 0 :(得分:3)

据我了解,您将必须处理父级组件中的选项卡切换逻辑(确定显示哪个选项卡)。即my-tabs-component的父项。

我认为有多种解决方法,这取决于您的逻辑有多复杂。

这些是我想到的情况:

每个标签都是一个组件

如果选项卡数量很少(我对此表示怀疑),则可以将ngComponentOutletng-container一起使用。

如果不这样做,则必须步入使用动态组件的底层。您可以利用嵌入式视图主机视图的功能。

ng-template创建的嵌入式视图,之所以这样称呼,是因为它无法自行显示任何内容,必须将其附加到 view容器

主机视图是您必须强制创建的组件。不过,您仍然必须将其附加到其他元素,最方便的方法是使用视图容器

您可以阅读有关嵌入式视图主机视图 here的更多信息。

IMO,视图容器的最合适的候选人是ng-container,您可以在组件类中进行查询并获得对ViewContainerRef API的访问权限。 / p>

我鼓励您尝试这种方法,因为它为您提供了一种在选项卡状态之间进行切换时保留选项卡状态的方法,这意味着您在将某些数据添加到{{之后,从TabATAbB 1}},然后回到TabA,它可能仍然具有您之前添加的内容。

这可以通过使用TabAViewContainerRef.detach()来实现。

大致上,这可能是一个实现:

ViewContainerRef.insert()
<my-tabs-component [tabs]="['tab1','tab2']">
 <ng-container #vcr></ng-container>
</my-tabs-component>

每个标签都是@Component({}) export class ParentComp { @ViewChild('vcr', { static: true, read: ViewContainerRef }) private vcr: ViewContainerRef; private prevLoadedTabName = 'tab1'; private compMap = new Map<string, ComponentRef<any>>(); private tabsFactories = { /* ... You components here */ }; loadTab (tabName) { this.compMap.set(this.prevLoadedTabName, this.vcr.detach()); this.prevLoadedTabName = tabName; if (this.compMap.has(tabName)) { this.compMap.insert(this.compMap.get(tabName)); return; } this.vcr.createComponent(this.tabsFactories[tabName]); } }

类似于上述情况。您可以使用ng-template代替ngComponentOutlet

如果您有多个ngTemplateOutlet,您仍然可以如上所述使用ng-template,但现在您想将ng-containerViewContainerRef.createEmbeddedView() / { {1}}。

为了从视图中获取ViewContainerRef.remove(),可以使用ViewContainerRef.clear()ng-template;

我可能错过了一些细节,但是我希望我能以一种精确的方式分享我的想法。