Angular 5 Adding a new instance of a component

2020-06-25 09:17发布

问题:

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:

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
  ],...


回答2:

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>