【问题标题】:Add child component to parent component and add parent to document将子组件添加到父组件并将父组件添加到文档
【发布时间】:2019-09-08 15:57:12
【问题描述】:

在 Angular 7 模态服务中,我正在创建一个模态 Stackblitz

模态只是一个添加到文档中的DIV,如下所示:

const modal = document.createElement('div');
modal.classList.add('modal');
modal.appendChild(this.element);

document.body.appendChild(this.modal);

modal 内容(this.element)是一个动态创建的组件。

我希望modal 也是一个动态添加的组件:

  1. 从 ModalComponent 创建模态(我认为类似于 2);
  2. 创建元素组件(完成);
  3. 添加元素组件作为模态组件的子组件;
  4. 将模态组件添加到文档。

有人可以帮我解决(3)和(4)吗?不知道该怎么做。

模态

export class Modal {
  protected modal: any = null;
  close() {
    this.modal.close();
  }
}

模态服务

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

@Injectable({
  providedIn: 'root'
})

export class ModalService {

  private component: ComponentRef<any>;
  private element: any;
  private stage: any;

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

  open(component: any, data: any): void {

    if(this.element) 
      return;

    const injector: Injector = ReflectiveInjector.resolveAndCreate([{ provide: 'modal', useValue: data }]);

    this.component = this.componentFactoryResolver.resolveComponentFactory(component).create(injector);

    this.component.instance.modal = this;

    this.application.attachView(this.component.hostView);

    this.element = (this.component.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;

    const modal = document.createElement('div');
    modal.classList.add('modal');
    modal.appendChild(this.element);

    document.body.appendChild(this.modal);

  }

  close(): void {

    this.application.detachView(this.component.hostView);
    this.stage.parentNode.removeChild(this.stage);
    this.component.destroy();
    this.element = null;

  }

}

【问题讨论】:

  • 你能更新你的 stackblitz 链接吗?
  • 完成...我误删了链接。
  • 抱歉,您的示例中的 ModalComponent 在哪里?我只看到 HelloComponent(我想这是元素)
  • 也许你正在寻找类似的东西stackoverflow.com/questions/44284026/…
  • @yurzui 我刚刚添加了 Modal.component.ts、Modal.component.html 和 Modal.component.css。我正在寻找的是用作 HelloComponent 的父级的 ModalComponent 并添加到文档中。而不是使用 document.createelement

标签: angular angular6 angular7 angular-components


【解决方案1】:

首先您需要动态创建该内部组件,然后使用ComponentFactory.create 方法中的projectableNodes 参数将其投影到您动态创建的ModalComponent 中。

ModalComponent 的模板中应该有 ng-content 标签:

<div class="stage">
  <div class="modal">
    <ng-content></ng-content>
  </div>
</div>

modal.service.ts

open(component: Type<Modal>): void {
  if (this.modalRef)
    return;

  this.elementRef = this.componentFactoryResolver
    .resolveComponentFactory(component)
    .create(this.injector);
  this.appRef.attachView(this.elementRef.hostView);
  this.elementRef.instance.modal = this;

  this.modalRef = this.componentFactoryResolver
    .resolveComponentFactory(ModalComponent)
    .create(this.injector, [[this.elementRef.location.nativeElement]]);
                                         \/
                      here we're projecting inner component into modal

  this.appRef.attachView(this.modalRef.hostView);

  document.body.appendChild(this.modalRef.location.nativeElement);
}


close(): void {
  this.appRef.detachView(this.elementRef.hostView);
  this.elementRef.destroy();
  this.elementRef = null;

  this.appRef.detachView(this.modalRef.hostView);
  this.modalRef.destroy();
  this.modalRef = null;
}

Forked Stackblitz

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多