Angular Create dynamic components in non deprecated way

59 Views Asked by At

I have three components PersonComponent, AddressComponent, CompanyComponent which already defined.

How can I create each component dynamically when I know the component name as text "PersonComponent"?

I injected the ViewContainerRef something similar way:

constructor(private viewContainerRef: ViewContainerRef) { }

When in the ngOnInit I try to create a component something similar

const componentRef = this.viewContainerRef.createComponent(PersonComponent);

It is ok. But how can I define a type instead of this component if I would like to parameterize this function via variable?

1

There are 1 best solutions below

2
Naren Murali On

Here is a simple example, where we set the components as values with a key as string, this will help you achieve dynamic rendering!

import { CommonModule } from '@angular/common';
import { Component, Type, ViewChild, ViewContainerRef } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { AComponent } from './a/a.component';
import { BComponent } from './b/b.component';
import { CComponent } from './c/c.component';
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, FormsModule],
  template: `
  Current: {{property}}<br/>
  <select [(ngModel)]="property">
    <option value="a">a</option>
    <option value="b">b</option>
    <option value="c">c</option>
  </select><br/>
    <button (click)="add()">Toggle Component</button>
    <div #container></div>
  `,
})
export class App {
  property: any = 'a';
  componentMap: { [key: string]: Type<any> } = {
    a: AComponent,
    b: BComponent,
    c: CComponent,
  };

  @ViewChild('container', { read: ViewContainerRef })
  container!: ViewContainerRef;

  private _counter = 1;

  constructor() {}

  add(): void {
    this.container.clear();
    // add the component to the view
    const componentRef = this.container.createComponent(
      this.componentMap[this.property]
    );

    // pass some data to the component
    componentRef.instance.index = this._counter++;
  }
}

bootstrapApplication(App);

stackblitz