I am trying to create a tab component with a structure similar to this:
<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>
I have conditional logic to ensure that the child components are only rendered via ng-content if they are on the selected tab with the following snippet:
<ng-content *ngIf="selected"></ng-content>
While this works as anticipated from a UI perspective, it appears the child elements are still being created internally even though they are never rendered. This is something I would like to avoid since it is causing database calls that won't be needed until the user selects the appropriate tab.
I have created a greatly simplified example to illustrate this. As you can see I have commented out the ng-content from the template of ChildComponent, but the call to console.log from the ThirdComponent is still firing.
Is there any way to prevent this from happening? I could probably create an interface on components that will be displayed in tabs and then call a custom method to trigger database calls rather than using the built-in Angular lifecycle methods, but I'd like to avoid that if at all possible.
Thanks for any help you can provide!
I found this article to be extremely helpful in solving my problem.
I changed the template of my tab-item component to look like this:
<ng-content *ngIf="selected"></ng-content>
<template *ngIf="selected && templateRef" [ngTemplateOutlet]="templateRef"></template>
With templateRef being an input property:
@Input() templateRef: TemplateRef<any>;
To use this component, I can now do the following:
<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>
Anything that's inside of a template will only be loaded when the tab is selected, preventing an extremely heavy initial page load.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With