问题
I want all the modals in our application to have a set of default options, and not have to apply them individually each time a modal is opened. So I created a service that extends NgbModal so I could overwrite the open
method since in NgBootstrap v1.1.2 there is no global config, but the entry component though listed in the feature module is not found.
I'm wondering if the service being provided in/core
doesn't see entry components loaded in a feature module? Using NgbModal directly the modal opens as you would expect, but changing the provided class doesn't seem to replace the service or swapping the DI from NgbModal
to the ModalService
produces this error:
ERROR Error: No component factory found for
ConfirmReleaseDocumentsModalComponent. Did you add it to
@NgModule.entryComponents?
Can anyone see why this might not work, or is there a better way to have a global config on a modal in NgBootstrap v1.1.2?
Service
import { Injectable } from '@angular/core';
import { NgbModal, NgbModalOptions, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
@Injectable()
export class ModalService extends NgbModal {
public open(content: any, options?: NgbModalOptions): NgbModalRef {
const defaultOptions: NgbModalOptions = {
backdrop: 'static',
keyboard: false
};
options = { ...defaultOptions, ...options }
return super.open(content, options);
}
}
App Module
@NgModule({
imports: [
BrowserModule,
CoreModule,
SharedModule
],
declarations: [
AppComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }
Core Module
@NgModule({
imports: [
CommonModule
],
providers: [
ModalService
]
})
export class CoreModule {
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
throwIfAlreadyLoaded(parentModule, 'CoreModule');
}
}
Feature Module
@NgModule({
imports: [
CommonModule,
SharedModule,
DocumentsRoutingModule
],
declarations: [
// ...
ConfirmReleaseDocumentsModalComponent
// ...
],
entryComponents: [
ConfirmReleaseDocumentsModalComponent
]
})
export class DocumentsModule { }
I initially tried to replace the provider, but this didn't work for some reason:
providers: [
{ provide: NgbModal, useClass: ModalService },
]
So then I tried using the service directly:
Component Opening Modal
constructor(
// private modalService: NgbModal, // original that works
private modalService: ModalService, // replaced with ModalService
) { }
public releaseBatchFromQueue(): void {
fromPromise(this.modalService
.open(ConfirmReleaseDocumentsModalComponent)
.result)
.pipe(
switchMap((result: boolean) => {
return (result)
? this.documentService
.releaseFromQueue(this.selectedIds)
: Observable.empty();
})
)
.subscribe(...);
}
Update
Also tried just invoking NgbModal directly in the service and not extending, but it produces the same entry component error:
import { Injectable } from '@angular/core';
import { NgbModal, NgbModalOptions, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
@Injectable()
export class ModalService {
constructor(
private modalService: NgbModal
) { }
public open(content: any, options?: NgbModalOptions): NgbModalRef {
const defaultOptions: NgbModalOptions = {
backdrop: 'static',
keyboard: false
};
options = { ...defaultOptions, ...options }
return this.modalService.open(content, options);
}
}
回答1:
It's related to lazy loading of modules. Entry components are NOT loaded if they are in a lazy loaded module, and must be moved up to shared. There is a posted GitHub issue related to entry components in modules not being available, but it's been open for over a year without much activity from contributors so it might be an issue and in the backlog for awhile - https://github.com/angular/angular/issues/14324.
来源:https://stackoverflow.com/questions/51689637/custom-ngbmodal-service-to-set-default-config-on-open-does-not-find-an-entry-com