How to destroy component created dynamically angular 8

醉酒当歌 提交于 2020-05-30 06:45:25

问题


I'm new to Angular. I have a button that every time I click it, it creates a component dynamically. I need each component to have a button or something that can destroy that component specifically. I have a function in the dynamic component that when I click on it, that component must be closed, but I don't know how to pass it to the function of the typescript file.Please help me.

app.component.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);
    }
}

conversacion.directive.ts

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

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

    constructor(public viewContainerRef: ViewContainerRef) { }

}

app.component.html

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

</div>

conversacion.component.html


<button (click)="removeObject()">delete me</button>
<div>
    this is a component dynamically
</div>

conversacion.component.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();
    }
}

回答1:


Below is an example where the dynamic component can "delete itself". The creator (app.component.ts) subscribes to the output of the dynamic component (simple.component.ts) and then invokes .destroy().

Also, the SimpleComponent has to be included in the module as an entryComponent since it is created dynamically.

Giphy: https://giphy.com/gifs/W2zx2dhNk4znnYFyGT

Example:


app.component.html

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

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

app.component.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) {}
}

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>

simple.component.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() {
  }

}

app.module.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 {}



来源:https://stackoverflow.com/questions/58701297/how-to-destroy-component-created-dynamically-angular-8

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!