繁体   English   中英

角度删除动态组件

[英]Angular Delete dynamic component

我正在使用Angular动态组件的帮助创建动态组件来推送烤面包机(通知程序或通知)

- ComponentFactoryResolve
-  EmbeddedViewRef
-  ApplicationRef
-  ComponentRef
-  Injectable
-  Injector

到目前为止,我所做的是创建要推送的组件并为其提供服务并在模块中注册了组件,它可以很好地推送组件,但是问题是当我尝试删除组件时,它获得了对上次推送组件的引用。

toast.component.ts(动态组件)


@Component({
  selector: 'uni-toast',
  template: `
    <div>
      <p (click)="closeToast()">{{ type }}</p>
      <p>{{ msg }}</p>
    </div>
  `,
  styles: []
})
export class ToastComponent implements AfterViewInit {
  @Input() index;
  @Input() type;
  @Input() msg;

  ngAfterViewInit() {}

      constructor(private toaster: ToastService) {}

  closeToast() {
    this.toaster.destroyToast(this.index);
  }
}

toast.service.ts

import { ToastComponent } from './toast.component';
import { ToastModule } from './toast.module';
import {
  ComponentFactoryResolver,
  EmbeddedViewRef,
  ApplicationRef,
  ComponentRef,
  Injectable,
  Injector
} from '@angular/core';
@Injectable({
  providedIn: ToastModule
})
export class ToastService {
  toastComponentRef: ComponentRef<ToastComponent>;
  private compIndex = 0;

  constructor(
    private componentFactoryResolver: ComponentFactoryResolver,
    private appRef: ApplicationRef,
    private injector: Injector
  ) {}

  private createToast() {
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(
      ToastComponent
    );
    const componentRef = componentFactory.create(this.injector);
    this.appRef.attachView(componentRef.hostView);

    const domElem = (componentRef.hostView as EmbeddedViewRef<any>)
      .rootNodes[0] as HTMLElement;
    document.body.appendChild(domElem);

    this.toastComponentRef = componentRef;
  }

  private bindToastData(type: string, msg: string) {
    this.toastComponentRef.instance.index = this.compIndex++;
    this.toastComponentRef.instance.type = type;
    this.toastComponentRef.instance.msg = msg;
  }

  public destroyToast(index) {
    this.appRef.detachView(this.toastComponentRef.hostView);
    this.toastComponentRef.destroy();
  }

  public toast(type: string, msg: string) {
    this.createToast();
    this.bindToastData(type, msg);
  }
} 

app.component.ts

import { Component } from '@angular/core';
import { ToastService } from 'toast';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(private toast: ToastService) {
    // pushing toasts
    this.toast.toast('Error', 'Invalid Credentials');
    this.toast.toast('success', 'success info');
    this.toast.toast('warn', 'warn info');
  }
} 

toast.module.ts

import { NgModule } from '@angular/core';
import { ToastComponent } from './toast.component';

@NgModule({
  declarations: [ToastComponent],
  imports: [],
  exports: [ToastComponent],
  entryComponents: [ToastComponent]
})
export class ToastModule {} 

我希望删除我单击的组件。

根据此演示,您可以像这样

  private removeDialogComponentFromBody() {
    this.appRef.detachView(this.dialogComponentRef.hostView);
    this.dialogComponentRef.destroy();
  }

我的博客展示了我如何破坏动态组件

import {
    ComponentFactoryResolver,
    Injectable,
    ComponentRef
} from "@angular/core";
@Injectable()
export class ComponentFactoryService {
    private componentRef: ComponentRef<any>;
    constructor(private componentFactoryResolver: ComponentFactoryResolver) {}

    createComponent(
        componentInstance: any,
        viewContainer: any
    ): ComponentRef<any> {
        const componentFactory = this.componentFactoryResolver.resolveComponentFactory(
            componentInstance
        );
        const viewContainerRef = viewContainer.viewContainerRef;
        viewContainerRef.clear();
        this.componentRef = viewContainerRef.createComponent(componentFactory);
        return this.componentRef;
    }

    destroyComponent() {
        if (this.componentRef) {
            this.componentRef.destroy();
        }
    }
}

您必须记住,组件.html文件不是实际显示的内容,Angular View Engine(Renderer2)使用它来创建浏览器显示的真实DOM。

这样,如果您想从视图中“销毁”组件,则可以执行此操作,这样Renderer2将从视图(DOM)中将其删除:

<div *ngIf="false">
    <uni-toast></uni-toast>
</div>

显示烤面包机并将其以编程方式隐藏的解决方案:

  • 使用烤面包机服务来保存一个布尔值,说明是否应该显示烤面包机
  • 呈现您的烤面包机组件的组件应使用此布尔值以ngIf有条件地显示它

您的服务还可以保留文本消息,图标,并且可以使用可观察对象推送事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM