我是Angular的新手。我有一个按钮,每次单击它都会动态创建一个组件。我需要每个组件都有一个按钮或可以专门破坏该组件的东西。动态组件中有一个函数,当我单击该组件时,必须关闭该组件,但我不知道如何将其传递给打字稿文件的函数。请帮帮我。
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();
}
}
答案 0 :(得分:0)
下面是一个动态组件可以“删除自身”的示例。创建者(app.component.ts)订阅动态组件(simple.component.ts)的输出,然后调用.destroy()
。
此外,由于SimpleComponent是动态创建的,因此必须作为entryComponent
包含在模块中。
Giphy:https://giphy.com/gifs/W2zx2dhNk4znnYFyGT
示例:
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 {}