Angular4 动态创建的组件如何通过API的调用销毁自身?

发布于 2022-09-05 10:32:42 字数 4115 浏览 16 评论 0

一般我们都是通过数据绑定DOM结构来实现删除数据从而删除DOM,但是现在有那么一个情景:
我通过<ng-template>配合自定义directive的方式,来动态创建了一个组件。我设计了一个命令模式,通过点击一个页面上的按钮来动态加载一个组件,按钮的代码是如下:

import {Component} from '@angular/core';
import {FocusDesignComponent} from '../../../class/focus-design-component';
import {BoxContainerComponent} from '../../design-components/box-container/box-container.component';

@Component({
  selector: 'app-box-tool',
  templateUrl: './box-tool.component.html',
  styleUrls: ['./box-tool.component.css']
})
export class BoxToolComponent {

  constructor(private focusDCL: FocusDesignComponent, private boxContainerComponent: BoxContainerComponent) {
  }

  createBoxPageComponent() {
    this.boxContainerComponent.create(this.focusDCL.getFocusDLC());
  }

}

绑定了 createBoxPageComponent() 到DOM上的click方法。
然后创建一个组件:

import {Component, ComponentFactoryResolver, ComponentRef, ViewChild} from '@angular/core';
import {PageComponent} from '../../../class/page-component';
import {DynamicLoadContainerDirective} from '../../../directive/design-component-directive/dynamic-load-container.directive';
import {FocusDesignComponent} from '../../../class/focus-design-component';
import {RemoveCommandDirective} from "../../../directive/design-component-directive/remove-command.directive";

@Component({
  selector: 'app-box-container',
  templateUrl: './box-container.component.html',
  styleUrls: ['./box-container.component.css']
})
export class BoxContainerComponent implements PageComponent {
  @ViewChild(DynamicLoadContainerDirective) dynamicLoadContainer: DynamicLoadContainerDirective;

  componentRef: ComponentRef<BoxContainerComponent>;

  constructor(private componentFactoryResolver: ComponentFactoryResolver, private focusDesignComponent: FocusDesignComponent) {
  }

  setFocus() {
    this.focusDesignComponent.setFocusDLC(this.dynamicLoadContainer);
  }

  create(dynamicLoadContainer: DynamicLoadContainerDirective) {
    this.componentRef = dynamicLoadContainer.viewContainerRef.createComponent(this.componentFactoryResolver.resolveComponentFactory(BoxContainerComponent));
  }

}

调用的是create方法。

好的,问题来了。我现在希望能够在这个组件的内部,有一个方法,可以销毁组件自己。我翻阅了很多资料,找到了相关的类似的方法:

  1. ViewContainerRef.clear():这个方法会清除<ng-template>容器内的所有组件。
  2. ComponentRef.destroy():这个方法是据说销毁组件自身。

这个componentRef对象,我要怎么在组件内部获取?,我不是明知故问啊,上面create方法创建的this.componentRef对象,是获取不到的。比如:

import {Component, ComponentFactoryResolver, ComponentRef, ViewChild} from '@angular/core';
import {PageComponent} from '../../../class/page-component';
import {DynamicLoadContainerDirective} from '../../../directive/design-component-directive/dynamic-load-container.directive';
import {FocusDesignComponent} from '../../../class/focus-design-component';
import {RemoveCommandDirective} from "../../../directive/design-component-directive/remove-command.directive";

@Component({
  selector: 'app-box-container',
  templateUrl: './box-container.component.html',
  styleUrls: ['./box-container.component.css']
})
export class BoxContainerComponent implements PageComponent {
  @ViewChild(DynamicLoadContainerDirective) dynamicLoadContainer: DynamicLoadContainerDirective;

  private componentRef: ComponentRef<BoxContainerComponent> = null;

  constructor(private componentFactoryResolver: ComponentFactoryResolver, private focusDesignComponent: FocusDesignComponent) {
  }

  setFocus() {
    this.focusDesignComponent.setFocusDLC(this.dynamicLoadContainer);
  }

  create(dynamicLoadContainer: DynamicLoadContainerDirective) {
    this.componentRef = dynamicLoadContainer.viewContainerRef.createComponent(this.componentFactoryResolver.resolveComponentFactory(BoxContainerComponent));
    console.log(this.componentRef);
  }

  destroySelf() {
    console.log(this.componentRef);
    this.componentRef.destroy();
  }

}

我底下添加了这样的一个方法 destroySelf()奇怪的是 this.componentRef 是 undefined。

另外,我希望能够把这个组件销毁自身的方法,封装成一个directive,然后监听键盘点击事件,从而删除这个组件。谁能告诉我,angular4 当中,到底组件销毁自身有什么可以主动调起的API吗?我一直就找不到,难道除了数据变动带来的组件变动,就没有办法销毁自身了?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

剧终人散尽 2022-09-12 10:32:42

贴一段代码,仅供你参考

import {
    Injectable,
    ApplicationRef,
    Injector,
    ComponentFactoryResolver,
    ReflectiveInjector,
    ComponentRef
} from '@angular/core';

@Injectable()
export class XXUtilService {

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

    public resolveComponent<T>(componentClass, provides): ComponentRef<T> {
        // 渲染组件,加入angular框架的控制
        let componentFactory = this.componentFactoryResolver.resolveComponentFactory<T>(componentClass);
        let componentInjector = ReflectiveInjector.resolveAndCreate(provides, this.injector);
        let componentRef = componentFactory.create(componentInjector);
        this.applicationRef.attachView(componentRef.hostView);
        return componentRef;
    }
}

...
...
let componentRef = this.xxUtilService.resolveComponent(componentClass,providers);
...
componentRef.destroy();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文