我正在尝试使用带有lazyLoading的ComponentFactoryResolver在模态弹出窗口中动态加载组件。 但是我收到错误消息:没有为ConfirmationComponent找到组件工厂。您是否将其添加到@ NgModule.entryComponents?
尽管ConfirmationComponent已添加在entryComponents中。从profilepage组件内部调用showModal函数,并将该组件传递给具有rxjs主题的app.module内部的服务。
在模式组件中,有一个对该主题的订阅,并将其传递给ComponentFactoryResolver。
如果不与单独的模块/延迟加载一起使用,则该模式确实可以工作。
app.module.ts
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule.withServerTransition({ appId: 'la' }),
AppRoutingModule,
BrowserAnimationsModule,
HttpModule
],
providers: [
ModalService,
],
bootstrap: [AppComponent]
})
export class AppModule { }
profile.module.ts
@NgModule({
declarations: [
ProfilePageComponent,
ConfirmationComponent,
],
imports: [
CommonModule,
FormsModule,
routing,
SharedModule
],
providers: [],
entryComponents: [
ConfirmationComponent,
],
})
export class ProfileModule { }
shared.module.ts
@NgModule({
declarations: [
ModalComponent,
],
imports: [
CommonModule
],
providers: [],
exports: [ModalComponent],
})
export class SharedModule { }
profile-page.component我正在将组件从此处传递给服务
modal.service component from the shared.module
@Component({
selector: 'la-profile-page',
templateUrl: './profile-page.component.html',
styleUrls: ['./profile-page.component.scss']
})
export class ProfilePageComponent implements OnInit {
constructor(private modalService: ModalService) { }
ngOnInit() {
}
confirm(certificate: Certificate) {
this.modalService.setComponent(ConfirmationComponent, {}, {});
}
}
modal.servce.ts
@Injectable()
export class ModalService {
public componentChanged = new Subject<any>();
componentChanged$ = this.componentChanged.asObservable();
constructor(
) { }
setComponent(component: any, inputs: any = {}, outputs: any = {}) {
this.componentChanged.next({ component: component, inputs: inputs, outputs: outputs });
}
closeModal() {
this.setComponent(null, {}, {});
}
}
modal.component.ts
@Component({
selector: 'la-modal',
styleUrls: ['modal.component.scss'],
templateUrl: 'modal.component.html',
animations: [modalAnimation]
})
export class ModalComponent implements OnInit {
component = null;
show = false;
@ViewChild('dynamicComponentContainer', {
read: ViewContainerRef
}) dynamicComponentContainer: ViewContainerRef;
constructor(
private resolver: ComponentFactoryResolver,
private controller: ModalService
) { }
ngOnInit() {
this.controller.componentChanged$.subscribe(component => {
this.setComponent(component.component, component.inputs, component.outputs);
});
}
setComponent(component: any, inputs: any, outputs: any) {
if (!component) {
this.show = false;
return;
} else {
this.show = true;
}
const inputProviders = Object.keys(inputs).map((inputName) => {
return {
provide: inputName,
useValue: inputs[inputName]
};
});
const outputProviders = Object.keys(outputs).map((outputName) => {
return {
provide: outputName,
useValue: outputs[outputName]
};
});
const resolvedInputs = ReflectiveInjector.resolve(inputProviders);
const injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.dynamicComponentContainer.parentInjector);
console.log(component);
const factory = this.resolver.resolveComponentFactory(component);
if (this.component) {
this.component.destroy();
}
this.component = factory.create(injector);
this.dynamicComponentContainer.insert(this.component.hostView);
inputProviders.forEach(prov => {
this.component.instance[prov.provide] = prov.useValue;
});
outputProviders.forEach(prov => {
this.component.instance[prov.provide].subscribe(prov.useValue);
});
}
closeModal() {
this.show = false;
}
deleteComponent(event) {
// this will be triggered when @modal.animation is done
if (event.fromState) {
this.dynamicComponentContainer.clear();
this.component = null;
}
}
}