问题:
我正在为非路由模块的角度设置延迟加载。在第7版中,我使用了NgModuleFactoryLoader及其函数load来延迟加载模块并获得模块的第一个入口点(用例中的服务)
this.loader.load('path-to-module')
.then(factory => {
const module = factory.create(this._injector);
return module.injector.get(EntryService);
});但是在角8中,NgModuleFactoryLoader是不推荐的,所以我不得不以这种方式加载模块:
import('path-to-module')
.then(m => m.MyModule)
.then(myModule => {
...
});这里的问题是,我无法在新的延迟加载中检索工厂和提供者(常春藤的想法之一--没有工厂)。
我已经尝试过的:
第一种解决方案(只使用JIT编译器,这不适合我们,因为我正在使用AOT编译器进行prod)
import('path-to-module')
.then(m => m.MyModule)
.then(myModule => {
return this._compiler.compileModuleAsync(myModule)
.then(factory => {
const module = factory.create(this._injector);
return module.injector.get(EntryService);
});
});第二种解决方案(脏和未完全检查)。它使用的是ngInjectorDef,这是常春藤的新特性,目前还没有任何描述的API ):
import('path-to-module')
.then(m => m.MyModule)
.then(myModule => {
const providers = myModule['ngInjectorDef'].providers; // Array<Providers>
... find EntryService in providers
});ngInjectorDef -是一个静态模块类属性,由角添加,并具有属性工厂、提供程序和导入。
来源:
No NgFactory file anymore部分)发布于 2019-07-23 21:04:07
我不会说访问ngInjectorDef属性是“肮脏的黑客”。是的,在任何地方都没有记载,因为,正如伊戈尔·米纳尔所说,常春藤在角度8中是可选的预览版,但许多私人功能已经在维克多·萨金的一些文章中提到过,比如directiveInject。
不应在providers属性中搜索服务。假设有20+提供程序,而且在生产过程中,EntryService名称也将缩小为t或k。
如果您使用常春藤-有一个名为createInjector的私有函数,它接受模块构造函数作为参数。
@Injectable()
export class EntryService {
public logFromEntryService(): void {
console.log('Logging from EntryService...');
}
}
@NgModule({
providers: [EntryService]
})
export class EntryModule {
public static getEntryService: () => EntryService = null;
constructor(injector: Injector) {
EntryModule.getEntryService = () => injector.get(EntryService);
}
}假设您有这样的代码,让我们使用一个动态导入来加载这个EntryModule
import { ɵcreateInjector as createInjector } from '@angular/core';
export class AppComponent {
constructor(private injector: Injector) {
this.loadEntryModule();
}
private async loadEntryModule(): Promise<void> {
const { EntryModule } = await import('./entry.module');
createInjector(EntryModule, this.injector);
EntryModule.getEntryService().logFromEntryService();
}
}createInjector用于实例化EntryModule,在实例化之后- getEntryService静态方法并不等于null。
我们还可以公开injector属性,例如:
public static injector: Injector = null;
constructor(injector: Injector) {
EntryModule.injector = injector;
}这可能被视为一个服务定位器,这是一种反模式。但取决于你!
https://stackoverflow.com/questions/57055895
复制相似问题