angular - 在引导模式中动态加载 Angular 分量

标签 angular typescript ng-bootstrap

我正在尝试在我的应用程序中创建一个可重用的 quickView 模式,以使用 ng-bootstrap modal library 动态加载任何组件。

就我加载文档中所示的相同示例组件而言,它工作正常,但不适用于我创建的用于测试的组件。

如何使用 quickView 模式创建动态组件以加载到 modal-body 中?

https://stackblitz.com/edit/angular-quickview

我使用简单的 if/else 根据名称 string 在模式中打开一个组件。

<button class="btn btn-lg btn-outline-secondary mr-2" (click)="open('default')">Launch default</button>
<button class="btn btn-lg btn-outline-danger mr-2" (click)="open('red')">Launch red</button>
<button class="btn btn-lg btn-outline-primary" (click)="open('blue')">Launch blue</button>
open(name: string) {
    if (name === "default") {
      const modalRef = this.modalService.open(NgbdModalContent);
      modalRef.componentInstance.name = "Default";
    } else if (name === "red") {
      const modalRef = this.modalService.open(RedComponent);
      modalRef.componentInstance.name = "Red";
    } else if (name === "blue") {
      const modalRef = this.modalService.open(BlueComponent);
      modalRef.componentInstance.name = "Blue";
    }
  }

我还尝试使用 componentFactoryResolver 将我的组件注入(inject)到 modal-body 中,但这也会引发错误 Error: Cannot read property 'viewContainerRef' of undefined

 <div class="modal-body">
      <ng-template quickView></ng-template>
 </div>
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(
        RedComponent
      );
      const viewContainerRef = this.quickView.viewContainerRef;
      viewContainerRef.clear();

      const componentRef = viewContainerRef.createComponent<any>(
        componentFactory
      );
      componentRef.instance.name = "Red";

最佳答案

您可以尝试添加模态服务,以便它可以解析ComponentFactory自定义组件,在这种情况下,模态将是单例。

modal.service.ts

import { Injectable, ComponentFactoryResolver } from "@angular/core";
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
@Injectable()
export class ModalService {
  constructor(
    private ngbModal: NgbModal,
    private componentFactoryResolver: ComponentFactoryResolver
  ) {}

  showDefaultModalComponent(theComponent: any, name: any) {
    const componenetFactory = this.componentFactoryResolver.resolveComponentFactory(
      theComponent
    );
    const modalRef = this.ngbModal.open(theComponent);
    modalRef.componentInstance.name = name;
    return modalRef;
  }

  showFeaturedDialog(theComponent: any, name: any) {
    const componenetFactory = this.componentFactoryResolver.resolveComponentFactory(
      theComponent
    );

    const modalRef = this.ngbModal.open(theComponent);
    modalRef.componentInstance.name = name;
    return modalRef;
  }
}

然后将该服务注入(inject)到主组件中。

export class NgbdModalComponent {
  constructor(private customModal: ModalService) {}

  open(name: string) {
    if (name === "default") {
      this.customModal.showDefaultModalComponent(NgbdModalContent, "Default");
    } else if (name === "red") {
      this.customModal.showFeaturedDialog(RedComponent, "Red");
    } else if (name === "blue") {
      this.customModal.showFeaturedDialog(BlueComponent, "Blue");
    }
  }
}

如果您想使用quickView指令,请检查您的示例无法工作的原因是否在RedComponent和BlueComponent中。 您添加了两次 @Component 装饰器,如下面的示例所示:

enter image description here

请参阅已编辑且正在运行的 Stackblitz 示例:

https://stackblitz.com/edit/angular-quickview-ykwz4i?file=src/app/modal-component.ts

注意:Angular 11 中的入口组件已被弃用。

关于angular - 在引导模式中动态加载 Angular 分量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66434541/

相关文章:

angular - <router-outlet> 在 Angular 9 中不起作用

javascript - 如何在 Angular 4 的 FormArray 中禁用 FormControl

unit-testing - 使用原生 View 封装时访问嵌套组件的DebugElement

javascript - 如何从http触发的函数输出到服务总线

angular - 我无法在 ubuntu 14.04 上为 angular-cli 安装最新版本

javascript - TypeORM AfterSave() 在创建后触发,但在查询时返回 NULL

javascript - Angular 2.x 选择 DOM 元素

ios - Ngbdropdown 单击事件不适用于 ios phonegap,角度 8 运行 cordova

滚动页面时,Angular 9+ 和 ng-bootstrap 工具提示在固定元素上失败,是否有比我更好的修复方法?

angular - 如何在不继承 NgbDatepickerI18n 的情况下为 Angular 中的 NgbDatepicker 进行翻译?