我有一个模态服务,负责打开一个签名为create<T>(component: Type<T>, params?: Object, module: Type<{}> = AppModule): Observable<ComponentRef<T>>
的模态对话框。模态服务的意思是问题是,当我导入已经导入的模块时,我收到错误Unexpected value 'undefined' declared by the module 'MyModule'
。研究表明,在尝试两次导入时,这是一个常见问题。
ModalService -
import { Injectable, ComponentRef, ComponentFactoryResolver, ViewContainerRef, ReflectiveInjector, Injector, Compiler, Type } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
import { AppModule } from '../../app.module';
@Injectable()
export class ModalService {
vcRef: ViewContainerRef;
constructor(private componentFactoryResolver: ComponentFactoryResolver,
private compiler: Compiler,
private injector: Injector) {
}
registerViewContainerRef(vcRef: ViewContainerRef): void {
this.vcRef = vcRef;
}
create<T>(component: Type<T>, params?: Object, module: Type<{}> = AppModule): Observable<ComponentRef<T>> {
let componentRef$ = new ReplaySubject();
this.compiler.compileModuleAndAllComponentsAsync(module)
.then(factory => {
let componentFactory = factory.componentFactories
.filter(item => item.componentType === component)[0];
const childInjector = ReflectiveInjector.resolveAndCreate([], this.injector)
let componentRef = this.vcRef.createComponent(componentFactory, 0, childInjector);
Object.assign(componentRef.instance, params);
componentRef$.next(componentRef);
componentRef$.complete();
});
return <Observable<ComponentRef<T>>> componentRef$.asObservable();
}
}
尝试使用属于FooComponent
的组件MyModule
打开模式对话框时的用法代码段。
import { MyModule } '../my.module';
this.modalService.create(FooComponent, {}, MyModule)
根据文档,如果组件被延迟加载,则在创建组件时需要该模块。
我的问题是,如何创建属于已加载或未加载的任何模块的组件。
编辑!如果我正在动态创建的组件没有任何依赖关系,这种情况很有效,这种情况不太可能经常发生。
请参阅Plunker here。我遇到问题的地方是文件app/core/modal/modal.service.ts
和app/crisis-center/crisis-list.component.ts
(第54行 - 模式应该打开的地方)。显示的错误是Uncaught (in promise): Error: No provider for MyService!
。不知道为什么,因为我从MyService
被定义为提供者的模块创建我的组件。
是否有更好的方法来实现这一目标?
TL; DR目标是创建一个服务(在我的情况下为ModalService
),无论它属于哪个模块,都可以创建任何组件。显然,它需要支持DI。
答案 0 :(得分:0)
每次出现此错误时,重新启动CLI都会解决问题。在深入研究我的代码之前先尝试一下是件容易的事。