4

I am using angular 5 and I want to create new instances of a component on demand.

This is the code I currently have:

app.component.ts:

import { Component } from '@angular/core';
import { MyComponent } from './mycomp/my.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  constructor() {}
  addCmp() {
    console.log('adding');
    // Add an instance of MyComponent code goes here ?
  }
}

app.component.html

<button (click)="addCmp()" >Add New MyComponent below</button>

MyComponent.html:

<div>I am MyComponent</div>

How can I do this?

  • 1
    What are you trying to achieve? – yurzui Nov 28 '17 at 15:59
  • That's not how angular works. Please provide more information on what your end goal is. – P_Andre Nov 28 '17 at 16:01
  • In basic terms, I have this component called MyComponent and I want addCmp() {} to add an instance of the component to the dom everytime addCmp() is called –  Nov 28 '17 at 16:06

2 Answers2

7

This is the way to create a component by your self: (Don't forget to destroy it! call destroy() on the componentRef to do this)

Parent Component:

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

constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

public createComponent(): void {
          const componentFactory = this.componentFactoryResolver.resolveComponentFactory(MyComponent);
          const componentRef = this.componentHolder.createComponent(componentFactory);
}

Parent Component HTML:

<button (click)="createComponent()">Add New MyComponent below</button>
<div #componentHolder ></div>

Add the MyComponent in the NgModule:

...
  imports: [
    BrowserModule,
    FormsModule,
    RouterModule.forRoot(appRoutes),
  ],
  entryComponents: [
    MyComponent
  ],...
G.Vitelli
  • 1,229
  • 9
  • 18
  • 1
    When I try to run createComponent() I get this error: ERROR Error: No component factory found for MyComponent. Did you add it to @NgModule.entryComponents? at noComponentFactoryError –  Nov 28 '17 at 16:14
  • 1
    Add MyComponent into the ngModule entryComponents, then it will work, i have update my answer. – G.Vitelli Nov 28 '17 at 16:17
  • How to delete such a dynamically created component? I'm adding components as editable table rows but how to delete a specific component? – Subhan Apr 28 '18 at 03:01
  • 1
    After creation of the component you will get a ComponentRef Object, on this Object you can call destroy(), this will cleanup everything and delete the component. About the Angular class https://angular.io/api/core/ComponentRef. – G.Vitelli Apr 30 '18 at 09:27
0

You could use an array in a parent component and grow the array every time you click the add button. In your app.component.html use a ngFor loop to iterate the array and then use the selector defined on MyComponent in the loop which will add a new instance for each iteration.

Keep in mind you never explain why you want to do this so there is no data being passed and no one can say which way is the best way to do this without knowing how you want to interact with your created components.

app.component.ts:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  myComponents:any[] = [];

  constructor() {}
  addCmp() {
    console.log('adding');
    this.myComponents.push(null);
  }
}

app.component.html

<button (click)="addCmp()" >Add New MyComponent below</button>
<ng-container *ngFor="let i of myComponents">
  <my-component></my-component>
</ng-container>
Igor
  • 60,821
  • 10
  • 100
  • 175