Reputation: 1
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?
Upvotes: -2
Views: 247
Reputation: 494
For passing data between same level component its better to use services
. define your variables there and use it in both components.
otherwise if you don't want to use services, first you need to share data between the child to parent using output
and EventEmitter
. Once received data in parent component share it to another child component using Input
.
Upvotes: 1