Angular 8 ngx-bootstrap modal No component factory found

Sam*_*aye 4 ngx-bootstrap angular angular8

I have a module which looks something like:

@NgModule({
  imports: [
    EmployeeRoutingModule,
  ],
  declarations: [
    ListEmployeeComponent,
    EmployeeDialogComponent,
  ],
  providers: [
    EmployeeService,
    BsModalService,
  ],
  entryComponents: [
    EmployeeDialogComponent,
  ]
})
export class EmployeeModule {
}
Run Code Online (Sandbox Code Playgroud)

And it is imported into the app module like so

{
  path: 'employee',
  loadChildren: './employee/employee.module#EmployeeModule'
},
Run Code Online (Sandbox Code Playgroud)

within the app.routing.ts.

When I try and use EmployeeDialogComponent in my EmployeeModule it keeps giving off the error

ERROR Error: No component factory found for EmployeeDialogComponent. Did you add it to @NgModule.entryComponents?
Run Code Online (Sandbox Code Playgroud)

如果我将其添加到模块中(让我们称之为SharedModule),则与应用程序运行时(在app.module.ts文件中)加载的方式相同。似乎是懒惰地使用它。

有什么问题,我该如何解决?

这是无法使用的最小模式示例:

import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {BsModalRef} from 'ngx-bootstrap';

@Component({
  selector: 'modal-content',
  template: `
    <div class="modal-body text-center">
      <p class="lead mb-5">{{ message }}</p>
      <button type="button" class="btn btn-lg btn-outline-secondary mr-5" (click)="decline()" >{{ btnNoText }}</button>
      <button type="button" class="btn btn-lg btn-success" (click)="confirm()" >{{ btnYesText }}</button>
    </div>
  `
})
export class ConfirmEmployeeModalComponent implements OnInit {
  @Output() result = new EventEmitter<boolean>();

  message = 'Are you sure?';
  btnNoText = 'No';
  btnYesText = 'Yes';

  constructor(public bsModalRef: BsModalRef) {
  }

  ngOnInit() {}

  confirm(): void {
    this.result.emit(true);
    this.bsModalRef.hide();
  }

  decline(): void {
    this.result.emit(false);
    this.bsModalRef.hide();
  }
}
Run Code Online (Sandbox Code Playgroud)

我在模块ListEmployeeComponent中有一个包含如下功能的组件:

import {
  Component,
  NgZone,
  ElementRef,
  OnInit,
  ViewContainerRef,
  PipeTransform,
  Pipe,
  ViewChild
} from '@angular/core';
import {FormControl} from '@angular/forms';
import {DialogService, BuiltInOptions} from "ngx-bootstrap-modal";
//import { EmployeeDialogComponent } from '../employee-dialog/employee-dialog.component';
import {EmployeeService} from "../employee.service";
import {LocalStorageUtilityService, NotificationService} from "../../common/common.services";
import * as _ from 'lodash';
//import { NotifyDialogComponent } from '../../common/dialog/notify-dialog/notify-dialog.component';
import {UserService} from "../../common/user.service";
import {ConfirmModalComponent} from "../../common/confirm-modal/confirm-modal.component";
import {BsModalService} from "ngx-bootstrap/modal";
import {EmployeeDialogComponent} from "../employee-dialog/employee-dialog.component";
import {ConfirmEmployeeModalComponent} from "../confirm-employee-modal/confirm-modal.component";

@Component({
  templateUrl: 'list-employee.component.html',
  styleUrls: ['./list-employee.component.css']
})
export class ListEmployeeComponent {
  constructor(
    private modalService: BsModalService,
    public _dialogService: DialogService,
    public _companyService: EmployeeService,
    public _notificationService: NotificationService,
    private userService: UserService,
  ) {
  }

  showAddEmployeeDialog = () => {
    this.modalService.show(ConfirmEmployeeModalComponent, {}).content.result.subscribe((details: any) => {
      }
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

ysf*_*ysf 6

我设法在此仓库中重现了您的问题,将其添加ModalModule.forRoot()EmployeeModule导入中可以修复该错误。

我也有类似的问题MatDialog,例如,当我想在已经创建的实例MatDialog(是可注入的)中使用延迟加载的模块中的组件时,我遇到了相同的错误。然后,我注意到与延迟加载的组件一起使用时,应该从头开始初始化服务。您的情况也正在发生类似的情况。

根据文档 ModalModule是用forRoot()like 导入的;

// RECOMMENDED
import { ModalModule } from 'ngx-bootstrap/modal';
// or
import { ModalModule } from 'ngx-bootstrap';

@NgModule({
  imports: [ModalModule.forRoot(),...]
})
export class AppModule(){}
Run Code Online (Sandbox Code Playgroud)

这意味着将BsModalService创建的全局单例实例并在整个应用程序中使用。而且它在初始化时不了解延迟加载的组件。

因此,解决方案是为延迟加载的模块初始化一个新实例,以便添加ModalModule.forRoot()EmployeeModule导入中将修复该错误。

@NgModule({
  imports: [
    EmployeeRoutingModule,
    ModalModule.forRoot()
  ],
  declarations: [
    EmployeeDialogComponent,
    ListEmployeeComponent,
  ],
  providers: [
    BsModalService,
  ],
  entryComponents: [
    EmployeeDialogComponent,
  ]
})
export class EmployeeModule {}
Run Code Online (Sandbox Code Playgroud)

但是请注意,这将创建一个BsModalService专用于的新实例,EmployeeModule并且它将不知道其外部的任何其他上下文,也不会意识到任何外部的上下文。简单来说,这意味着您不能在EmployeeModule上下文以外的任何其他位置与该特定对话框交互(例如关闭它)。

  • 究竟。而且我只是检查了这是否是ngx-bootstrap问题,并发现了[this](https://github.com/valor-software/ngx-bootstrap/issues/2356)显然,这几乎是一个已知问题2年没有任何进展:/,他们在那里也提出了相同的解决方案。 (2认同)