3

I want to create components dynamically from an array. #cmp1, #cmp2, #cmp3 should be dynamic how can this be achieved

 <my-component #cmp1></my-component> 
 <my-component #cmp2></my-component> 
 <my-component #cmp3></my-component> 

 componentList: string[] = ['cmp1', 'cmp2', 'cmp3']

And I have to fetch one these components dynamically at runtime based on a string value

 let reqiuredComponent = 'cmp2'
 let captureComponent: MyComponent = @ViewChild(requiredComponent)
Flyii
  • 1,105
  • 1
  • 12
  • 21
Jaya Venkat
  • 65
  • 1
  • 6
  • 4
    Why not use ViewChildren? You get a QueryList of your components, and you can get first, pass to array.... – Eliseo May 04 '19 at 09:10

2 Answers2

2

This can be achieved without assigning dynamic template reference [#cp1, #cp2 ...] also.

In your .html

<div #container>
 <ng-container #main></ng-container>
</div>

In your .ts

  @ViewChild('main', {read: ViewContainerRef}) vcr: ViewContainerRef;
  @ViewChild('container') container: ElementRef;

  constructor(private cfr: ComponentFactoryResolver,
              private el: ElementRef) {}

  ngAfterViewInit() { 
    for(let i=0; i<3; i++) {
      this.vcr.createComponent(this.cfr.resolveComponentFactory(MyComponent)); 
    }           
  }

Now to access your different component

console.log(this.container.nativeElement.childNodes[1]     //childNodes[0|1|2]

Like this you can assess all the functionality of ElementRef like ...childNodes[0].innerHTML

Prashant
  • 375
  • 4
  • 7
1

if you have multiple dynamically created components, you can fetch one of these components dynamically at runtime by ViewChildren

in parent component:

import { .., ViewChildren,QueryList } from '@angular/core';
...
@ViewChildren(MyComponent) mycomponents!: QueryList<MyComponent>;
// now you can fetch second component by:
this.mycomponents.toArray()[1]
suhailvs
  • 20,182
  • 14
  • 100
  • 98
  • Thank you for giving directions towards ViewChildren. https://angular.io/api/core/ViewChildren lists some other options to use it. – burkay Apr 17 '23 at 15:43