首页 > 解决方案 > Angular:组件内包含的模态窗口渲染

问题描述

我嵌套了一些不同的 Angular 模块。每个人都有自己的服务等。问题是当我想从嵌入式模块打开模式窗口时:这些元素打开并且工作正常,但在它自己的模块内部。我已经搜索过,但找不到任何特定的解决方案来打开所有组件之外的模式窗口(在浏览器主区域,如常规模式窗口)。

显示实际结果的 GIF:

描述

我尝试更改 z-index(在主类上,分隔一个,在 html 标记中硬编码)、禁用背景和许多其他(讨厌的)技巧,但似乎没有一个能解决这个问题。

html 看起来像这样:

<div bsModal #modalFormPlanta="bs-modal" [config]="{backdrop: false}">
<div class="modal-dialog modal-md">
    <div class="modal-content">
        <app-formulario-planta-cliente *ngIf="showFormAddPlanta" [Client]="Client" [action]="PlantaSeleccionada?.id != null" [element]="PlantaSeleccionada" (finish)="closeFormPlanta($event)"></app-formulario-planta-cliente>
    </div>
</div>

该元素位于 html 文件的末尾。在所有之外<div>

已经在 bsModal 上尝试过:

style="z-index: 9999 !important"
tabindex="-1"
class="modal fade"
data-backdrop="false"

以及这个组件的相关代码:

    @ViewChild('modalFormPlanta') modalFormPlanta: ModalDirective;
    
    public openEditForm(elem) {
        this.PlantaSeleccionada = elem;
        this.showFormAddPlanta = true;
        this.modalFormPlanta.show();
    }

    public closeFormPlanta(event) {
        if (event) {
            this.PlantaSeleccionada.Cliente = event;
            this.loadPlantas();
        }
        this.modalFormPlanta.hide();
    }

你能建议我任何解决方案来打开浏览器区域上的每个模式窗口(不在任何组件内)。

非常感谢!

标签: angularmodal-dialogfrontend

解决方案


您可以生成模态组件并将其附加到 f.ex 的某个根节点。AppComponent elementRef; 在这里我做了一个分叉的DEMO(点击“客户”然后“显示模式”)。它从延迟加载的模块组件中附加 Modal 组件。

首先,在 AppComponent 中获取其 nativeElement 的引用,以便稍后在附加模式时访问它:

this.nativeElement = this.elRef.nativeElement

对于 Modal 组件添加所需的样式,例如position: absolute; top: 0; left: 0 然后将其导入,entryComponents因为您将动态创建它。

然后实例化 Modal 并附加到主机:

  showModal() {
    this.appendComponentToBody(ModalComponent);
  }

  appendComponentToBody(component: any) {
    // 1. Create a component reference from the component
    const componentRef = this.componentFactoryResolver
      .resolveComponentFactory(component)
      .create(this.injector);

    // 2. Attach component to the appRef so that it's inside the ng component tree
    this.appRef.attachView(componentRef.hostView);

    // 3. Get DOM element from component
    const domElem = (componentRef.hostView as EmbeddedViewRef<any>)
      .rootNodes[0] as HTMLElement;

    const rootElementRef = this.injector.get(this.appRef.componentTypes[0])
      .nativeElement;
    // 4. Append DOM element to the body
    rootElementRef.appendChild(domElem);
  }

从这个 repoappendComponentToBody借来的函数的一些代码


推荐阅读