Folder structure of the project (for reference)
dynamic-container.component.html
<h1>Dynamic component in angular</h1>
<ul>
<li (click)="createComponent(productNames.mobile)">Mobile</li>
<li (click)="createComponent(productNames.laptop)">Laptop</li>
<li (click)="createComponent(productNames.watch)">Watch</li>
<li (click)="createComponent(productNames.burger)">Burger</li>
<li (click)="createComponent(productNames.ovan)">Ovan</li>
</ul>
<div class="display black-border">
<ng-container #container></ng-container>
</div>
dynamic-container.component.ts
@Component({
selector: 'app-dynamic-container',
templateUrl: './dynamic-container.component.html',
styleUrls: ['./dynamic-container.component.css']
})
export class DynamicContainerComponent implements OnInit{
@ViewChild('container',{read:ViewContainerRef,static:true}) container:ViewContainerRef|any
componentMap=new Map<string,ComponentRef<any>>()
index=0
productNames:any={
mobile:'mobile',
laptop:'laptop',
watch:'watch',
burger:'burger',
ovan:'ovan'
}
createComponent(name:string){
const compType=this.getComponentType(name)
const comp=this.container.createComponent(compType) // comp store the reference returned by the method
let uniqueName=name+' - '+this.index.toString()
this.index++
comp.instance.name=uniqueName // comp has a instance property
}
getComponentType(name:string):Type<any>
{
let type: Type<any>=MobileComponent
switch(name)
{
case this.productNames.mobile:{
type=MobileComponent
break
}
case this.productNames.laptop:{
type=LaptopComponent
break
}
case this.productNames.burger:{
type=BurgerComponent
break
}
case this.productNames.ovan:{
type=OvanComponent
break
}
case this.productNames.watch:{
type=WatchComponent
break
}
}
return type
}
}
Below dynamic-container you can see there is a component called mobile(refer the image).
In mobile.component.ts
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-mobile',
templateUrl: './mobile.component.html',
styleUrls: ['./mobile.component.css']
})
export class MobileComponent {
@Input() name:string=''
}
In mobile.component.html
<h4>{{name | titlecase}}</h4>
In case you want to see app.component.html
<app-dynamic-container></app-dynamic-container>
and app.module.ts
@NgModule({
declarations: [
AppComponent,
DynamicContainerComponent,
MobileComponent,
LaptopComponent,
BurgerComponent,
WatchComponent,
OvanComponent
],
providers: [],
bootstrap: [AppComponent],
imports: [
BrowserModule,
CommonModule
],
exports:[DynamicContainerComponent]
})
export class AppModule { }
I searched if there is any way of using @Input without property binding but found @Input need [property binding] and is done between parent and child component.
But you can see here it is done between 2 same level components that is dynamic-container and mobile.
So, I am not able to understand how it is happening under the hood or am I missing any concept. I found this in a youtube video here is the link - (https://www.youtube.com/watch?v=GE_lxrbFNtI&t=222s). Can anyone please help me understand this?