如何销毁动态创建的组件 Angular 8

Jes*_*ans 5 angular angular8

我是角度新手。我有一个按钮,每次单击它时,它都会动态创建一个组件。我需要每个组件都有一个按钮或可以专门销毁该组件的东西。我在动态组件中有一个函数,当我单击它时,该组件必须关闭,但我不知道如何将它传递给打字稿文件的函数。请帮助我。

应用程序组件.ts

import { Component, OnInit, ComponentFactoryResolver, ViewChild, Input,ComponentRef,ViewContainerRef } from '@angular/core';
import {ChatService} from "./services/chat.service";
import {Mensaje} from "./models/mensaje";
import {ConversacionComponent} from "./components/conversacion/conversacion.component";
import {ConversacionDirective} from "./components/conversacion/conversacion.directive";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
    providers:[ChatService]
})
export class AppComponent {
    @ViewChild(ConversacionDirective, {static: true}) eldinamico: ConversacionDirective;
  title = 'chat';

  constructor(private cfr: ComponentFactoryResolver){  }
    ngOnInit() { }


    componenteDinamico(mensaje: string) {
        const cf = this.cfr.resolveComponentFactory(ConversacionComponent);
        const vcr = this.eldinamico.viewContainerRef;
        vcr.createComponent(cf, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

对话.directive.ts

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
    selector: '[appConversacionDinamica]'
})
export class ConversacionDirective {

    constructor(public viewContainerRef: ViewContainerRef) { }

}
Run Code Online (Sandbox Code Playgroud)

应用程序组件.html

<input type="text" #mensaje><br/>
<button (click)="componenteDinamico(mensaje.value)"> Crear Componente </button>
<br/>
<div class="orden">
  <ng-template appConversacionDinamica></ng-template>

</div>
Run Code Online (Sandbox Code Playgroud)

conversacion.component.html


<button (click)="removeObject()">delete me</button>
<div>
    this is a component dynamically
</div>
Run Code Online (Sandbox Code Playgroud)

会话组件.ts

import {Component, Input, OnInit, Output, EventEmitter,ViewChild,ElementRef,ComponentRef} from '@angular/core';

@Component({
  selector: 'app-conversacion',
  templateUrl: './conversacion.component.html',
  styleUrls: ['./conversacion.component.css']
})
export class ConversacionComponent implements OnInit {
    mensaje: string;   
    vcr:any; 

  constructor() {}

  ngOnInit() {}   

  removeObject(){
    this.vcr.destroy();
    }
}
Run Code Online (Sandbox Code Playgroud)

chr*_*ian 6

下面是动态组件可以“删除自身”的示例。创建者 (app.component.ts) 订阅动态组件 (simple.component.ts) 的输出,然后调用.destroy().

此外,SimpleComponent 必须作为 an 包含在模块中,entryComponent因为它是动态创建的。

吉菲: https: //giphy.com/gifs/W2zx2dhNk4znnYFyGT

例子:


应用程序组件.html

<h1>App</h1>
<button (click)="onClickAdd()">Create</button>

<br>
<hr>
<ng-template #componentsContainer></ng-template>

Run Code Online (Sandbox Code Playgroud)

应用程序组件.ts

import {
  Component,
  ViewChild,
  ViewContainerRef,
  ComponentFactoryResolver,
  ComponentRef,
  OnDestroy
} from '@angular/core';
import { Subscription } from 'rxjs';
import { tap } from 'rxjs/operators';
import { SimpleComponent } from './simple/simple.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnDestroy {
  @ViewChild('componentsContainer', { read: ViewContainerRef }) container: ViewContainerRef;
  private subs: Subscription[] = [];

  ngOnDestroy() {
    // unsubscribe from all on destroy
    this.subs.forEach(sub => sub.unsubscribe());
  }

  onClickAdd = () => {
    const factory = this.componentFactoryResolver.resolveComponentFactory(SimpleComponent);
    const component = this.container.createComponent(factory);

    component.instance.numberCreated = this.container.length;

    // subscribe to component event to know when to delete
    const selfDeleteSub = component.instance.deleteSelf
      .pipe(tap(() => component.destroy()))
      .subscribe();

    // add subscription to array for clean up
    this.subs.push(selfDeleteSub);
  }

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
}

Run Code Online (Sandbox Code Playgroud)

simple.component.html

<button (click)="deleteSelf.emit()" style="background-color: blue; color: white">delete self</button>
<p>Dynamic Component</p>
<p>Number at time of creation: {{ numberCreated }}</p>
<hr>
Run Code Online (Sandbox Code Playgroud)

简单组件.ts

import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';

@Component({
  selector: 'app-simple',
  templateUrl: './simple.component.html',
  styleUrls: ['./simple.component.css']
})
export class SimpleComponent implements OnInit {
  @Output() deleteSelf: EventEmitter<void> = new EventEmitter<void>();
  @Input() numberCreated: number;

  constructor() { }

  ngOnInit() {
  }

}
Run Code Online (Sandbox Code Playgroud)

应用程序模块.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SimpleComponent } from './simple/simple.component';

@NgModule({
  declarations: [AppComponent, SimpleComponent],
  imports: [BrowserModule, AppRoutingModule],
  providers: [],
  bootstrap: [AppComponent],
  entryComponents: [SimpleComponent]
})
export class AppModule {}

Run Code Online (Sandbox Code Playgroud)