我正在尝试创建一个类似于此结构的制表符组件:
<tabs>
<tab-item [title]="'Tab 1'">
**child component that makes database calls in NgOnInit or NgAfterViewInit**
</tab-item>
<tab-item [title]="'Tab 2'">
**child component that makes database calls in NgOnInit or NgAfterViewInit**
</tab-item>
<tab-item [title]="'Tab 3'">
**child component that makes database calls in NgOnInit or NgAfterViewInit**
</tab-item>
</tabs>
我有条件逻辑来确保子组件仅通过ng-content呈现,如果它们位于选定的选项卡上,并带有以下代码段:
<ng-content *ngIf="selected"></ng-content>
虽然从UI的角度来看这是预期的,但是看起来子元素仍在内部创建,即使它们从未被渲染过。这是我想避免的,因为它导致在用户选择适当的选项卡之前不需要数据库调用。
我创建了一个非常simplified example来说明这一点。正如您所看到的,我已经从ChildComponent的模板中注释掉了ng-content,但是仍然从第三方组件调用console.log。
有没有办法防止这种情况发生?我可以在组件上创建一个接口,它将显示在选项卡中,然后调用自定义方法来触发数据库调用,而不是使用内置的Angular生命周期方法,但我想尽可能避免这种情况。
感谢您提供的任何帮助!
答案 0 :(得分:1)
我发现this article对解决我的问题非常有帮助。
我将tab-item组件的模板更改为:
<ng-content *ngIf="selected"></ng-content>
<template *ngIf="selected && templateRef" [ngTemplateOutlet]="templateRef"></template>
使用templateRef作为输入属性:
@Input() templateRef: TemplateRef<any>;
要使用此组件,我现在可以执行以下操作:
<tabs>
<tab-item [title]="'Tab 1'">
**static content**
</tab-item>
<tab-item [title]="'Tab 2'" [templateRef]="tab2"></tab-item>
<tab-item [title]="'Tab 3'" [templateRef]="tab3"></tab-item>
<template #tab2>
**child component that makes database calls in NgOnInit or NgAfterViewInit**
</template>
<template #tab3>
**child component that makes database calls in NgOnInit or NgAfterViewInit**
</template>
</tabs>
只有在选中标签时才会加载模板内的任何内容,从而防止初始页面加载量过大。