1

I'm trying to call a component dynamically. I have a component that gets child component type as input(string). for example detail.itemType = 'Accordion'. i want this component to call the right child component based on the type but not using if statement



import { ContentDetail, ContentFields } from 'app/models/content/content.model';
import { Component, OnInit, Input, ComponentFactoryResolver, ViewChild, ViewContainerRef, ComponentRef } from '@angular/core';
import { AccordionComponent } from './accordion-paragraph/accordion-paragraph.component';

@Component({
  selector: 'app-content-components',
  templateUrl: './content-components.component.html',
  styleUrls: ['./content-components.component.scss']
})
export class ContentComponentsComponent implements OnInit {

  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

  @ViewChild('createComponent', {static: true, read: ViewContainerRef }) entry: ViewContainerRef;
  @Input() public detail: ContentDetail = new ContentDetail();


  ngOnInit() {
      let component: any = null;
      if(this.detail.itemType === 'Accordion'){
        component = AccordionComponent;
        let factory = this.componentFactoryResolver.resolveComponentFactory(component);
        let componentRef:ComponentRef<any> = this.entry.createComponent(factory);
      }
  }



}

so I want to add Accordion dynamically instead of using if statement. something like:

   let componentName = Accordion
   component = componentName + Component;
   let factory = this.componentFactoryResolver.resolveComponentFactory(component);
   let componentRef:ComponentRef<any> = this.entry.createComponent(factory);

is it possible to add component name like that?

Shlok Nangia
  • 2,355
  • 3
  • 16
  • 24
John T
  • 45
  • 1
  • 8

2 Answers2

1

you can not change component name like this ,as Component is object not string.you can create ComponentArray that will old all your components and according to contidion you can pass that component from the array, like this

myComponents = [comp1, copm2,...]
if(item==='condition')
   let component =  myComponents[0]
  • Thanks Shilpa, what if i don't have the order on the array? how would i know which one of the components to call? – John T May 12 '20 at 01:54
  • Change Array to object Array and store itemType as well along with Component and you can iterate through Array when it matches with selected itemType return that Component. – Shilpa Lalwani May 12 '20 at 05:02
1

Create a service that returns component name based on this.detail.itemType and then use this code:

    let component = this.contentService.getComponentbytype(this.detail.itemType)
    if(component){
      let factory = this.componentFactoryResolver.resolveComponentFactory(component);
      let componentRef:ComponentRef<any> = this.entry.createComponent(factory);
      componentRef.instance.fields = this.fields;
    }

and in your service file:

public getComponentbytype(_itemType: string): any {
let component: any;

if (_itemType) {
    switch (_itemType) {
        case 'specificItemType':{
            component = specificItemTypeComponent;
            break;
        }
        default: {
            component = null;
            break;
        }
    }
}

return component
}
Ramin Ahmadi
  • 619
  • 5
  • 13