I want to create custom Tabs component that will be able to display contents of [root] inside itself.
It works perfectly when I use selectors in html tags (<tab1>
), but I do not always know what the selector would be. Tabs are basically components so I need a way to render component to the view
My Tab.ts which should display the root component inside viewport
@Component({
selector: 'tab',
template:
`<div [hidden]="!active">
<ng-content></ng-content>
</div>`
})
export class Tab {
@Input('tabTitle') title: string;
@Input() active = false;
@Input('root') root: any;
}
Then here is Tabs.ts which glues tabs together (enables you to switch between them)
@Component({
selector: 'tabs',
template:
`<div class="tabbar">
<div class="tab-button" *ngFor="let tab of tabs" (click)="selectTab(tab)">
<a href="#">{{tab.title}}</a>
</div>
</div>
<ng-content></ng-content>`
})
export class Tabs implements AfterContentInit {
@ContentChildren(Tab) tabs: QueryList<Tab>;
ngAfterContentInit() {
let activeTabs = this.tabs.filter((tab) => tab.active);
if (activeTabs.length === 0) {
this.selectTab(this.tabs.first);
}
}
selectTab(tab: Tab) {
this.tabs.forEach(tab => tab.active = false);
tab.active = true;
if (this.menu) {
this.menu.active = false;
}
}
}
Then I have this template that should enable me to use tabs and works in all cases
<tabs>
<tab tabTitle="Tab 1">
<tab-home></tab-home>
</tab>
<tab tabTitle="Tab 2">
<tab-second></tab-second>
</tab>
<tab tabTitle="Tab 3">
Tab 3 content
</tab>
</tabs>
But at the end I would like do be able to do it like this:
<tabs>
<tab *ngFor="let tab of tabs" [title]="tab.title">
{{ tab.component }}
</tab>
</tabs>
Instead of tab.component I need to show the rendered view of component but without selector it doesn't seem to work.
So I need a way to inject rendered view from component into template without directive (as I never know what the directive will be)