I need to load the components dynamically into the tabs in angular. I have a parent component which has angular tabs in it. Inside the tab control, I need to load the child components dynamically.
Initially when the Tabs are loaded it should be loaded with a component1, and on some user interactions it should trigger the event which would load additional tabs and other child components to be loaded inside it.
My requirement is load any child components dynamically inside the each tabs.
I am facing issues in loading the child components dynamically inside the tab and not understanding how to proceed further?
I have created a POC for demo in stackblitz
My Parent component is as follows:
import {Component, ViewChild, AfterViewInit, TemplateRef, ComponentRef, ViewContainerRef} from '@angular/core';
import { ComponentFactoryResolver } from '@angular/core';
import { Component1 } from './Component1';
import { Component2 } from './Component2';
@Component({
selector: 'home',
template: `<mat-tab-group class="demo-tab-group">
<mat-tab *ngFor="let tab of homepageTabs; let i = index" label="{{tab.label}}">
<!--Component1 and Component2 to be loaded here... what is the correct container object which can hold dynamic components ? -->
<ng-template #container>{{tab.templateRef}}</ng-template>
</mat-tab>
</mat-tab-group>`
})
export class HomeComponent {
homepageTabs: any;
@ViewChild('container', { read: ViewContainerRef }) dynamicTabPlaceholder;
constructor(private cfr: ComponentFactoryResolver)
{
//Need to instantiate the components Component1 & Component2 dynamically and load here into the homepageTabs List
const factory = this.cfr.resolveComponentFactory(Component1);
const componentRef = this.dynamicTabPlaceholder.createComponent(factory);
this.homepageTabs = [
{
label: 'HomeLabel',
//templateRef: Component1,//How to assign the component1 instance here?
tabTitle: 'HomeTitle'
},
{
label: 'App Details',
//templateRef: Component2,
tabTitle: 'App Details'
}
];
}
}
My child component looks like below,
import {Component} from '@angular/core';
@Component({
selector: 'Component1',
template: `Component1 Loaded
<md-list>
<md-list-item class="md-2-line" ng-repeat="item in workbookSheetsList">
<md-checkbox ng-model="item.done"></md-checkbox>
<div class="md-list-item-text">
<h3>{{item.name}}</h3>
</div>
</md-list-item>
</md-list>
`,
//styleUrls: ['./tabs-template-label-example.css']
})
export class Component1 {
workbookSheetsList = [{ "name": "TestReport" }, { "name": "SimpleReport" }, { "name": "Highlighting" }, { "name": "CalculatedColumns" }, { "name": "DateFormat" }, { "name": "KPIIndicator" }];
constructor(){
}
}
I am getting the below error when I run the application, which indicates that I am not able to get the correct container reference to create/load the component?
TypeError: Cannot read property 'createComponent' of undefined
at new HomePageComponent (homepage.component.ts:76)
at createClass (core.es5.js:10946)
at createDirectiveInstance (core.es5.js:10764)
at createViewNodes (core.es5.js:12205)
at createRootView (core.es5.js:12100)
at callWithDebugContext (core.es5.js:13486)
I am struck here and not sure how to load the child components to be loaded inside a tab :-
<mat-tab-group class="demo-tab-group">
<mat-tab *ngFor="let tab of homepageTabs; let i = index" label="{{tab.label}}">
<div class="demo-tab-content">
<!--Component1 and Component2 to be loaded here... what is the correct container object which can hold dynamic components ? -->
<ng-template #container>{{tab.templateRef}}</ng-template>
</div>
</mat-tab>
</mat-tab-group>
{
label: 'HomeLabel',
//templateRef: Component1,//How to assign the component1 instance here?
tabTitle: 'HomeTitle'
},
Can anybody help me with this issue and let me know how to proceed further?
https://stackblitz.com/edit/angular-e7fnhd?file=app%2Fhome.component.ts
I think the answer here is to use the angular
router functionality to load the dynamic content you are referring to.
The key thing is that I learned the hard way is to NOT make the main component of the application a route. So do not place the router-outlet
in the index.html
file but as an element of the app-component
.
Check out my stackblitz
for a demo
This way you are also able to build a static layout for you application that remains the same on the inner content changes.
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