[英]Angular 8 CLI: How to lazy load non-routable feature module with providers
嘿,
我试着遵循这些指南: https : //angular.io/guide/lazy-loading-ngmodules
但是官方文档只用Router来解决这个问题(哇哇.Qngular docs不是最理想的)
https://netbasal.com/the-need-for-speed-lazy-load-non-routable-modules-in-angular-30c8f1c33093
所以这篇中篇文章正是我所寻找的。 我唯一的问题是它不会工作。
ANGULAR.JSON
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"lazyModules": [
"path/to/components#MyModule"
],
APP MODULE
providers: [
SystemJsNgModuleLoader, // without this I get NullInjectorError
CookieService,
{ provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader }, // this doesnt seem to do anything
{
provide: HTTP_INTERCEPTORS, useClass: AuthHeaderInterceptor, multi: true,
}
],
bootstrap: [AppComponent]
MODULE
@NgModule({
imports: [
CommonModule,
MatButtonModule,
MatIconModule,
],
declarations: [
MyModule.rootComponent
],
providers: [MyService],
entryComponents: [MyModule.rootComponent]
})
export class MyModule{
static rootComponent = MyComponent;
static forRoot(): ModuleWithProviders {
return {
ngModule: MyModule,
providers: [MyService]
};
}
}
服务
@Injectable()
export default class MyService {}
...
懒惰的负载提供商
export interface LAZY_MODULES {
'MyModule': string;
}
export const lazyMap: LAZY_MODULES = {
'MyModule': 'path/to/components#MyModule'
};
export const LAZY_MODULES_MAP = new InjectionToken('LAZY_MODULES_MAP', {
factory: () => lazyMap
})
懒惰的指令
@Directive({
selector: '[lazyLoadModule]'
})
export class LazyLoadModuleDirective implements OnInit, OnDestroy {
@Input('lazyLoadModule') moduleName: keyof LAZY_MODULES;
private moduleRef: NgModuleRef<any>;
constructor(
private vcr: ViewContainerRef,
private injector: Injector,
private loader: NgModuleFactoryLoader,
@Inject(LAZY_MODULES_MAP) private modulesMap
) { }
ngOnInit() {
this.loader
.load(this.modulesMap[this.moduleName])
.then((moduleFactory: NgModuleFactory<any>) => {
this.moduleRef = moduleFactory.create(this.injector);
const rootComponent = (moduleFactory.moduleType as ModuleWithRoot)
.rootComponent;
const factory = this.moduleRef.componentFactoryResolver.resolveComponentFactory(
rootComponent
);
this.vcr.createComponent(factory);
});
}
ngOnDestroy() {
this.moduleRef && this.moduleRef.destroy();
}
}
在APP组件HTML
<ng-container *ngIf="showModule"
lazyLoadModule="MyModule">
</ng-container>
结果是:
如果我使用没有包装器对象的SystemJsNgModuleLoader,则Chunking工作 (webpack报告它构建了一个路径到组件my-module.ts )在开发工具中我得到SystemJsNgModuleLoader的NullinjectorError
如果我直接在提供程序中使用SystemJsNgModuleLoader我在开发控制台中没有出错。 Chunking也有效。 但是在网络控制台中, 模块永远不会被加载 ,即使我直接在app控制器中设置showModule = true ...
上面的例子很有效。 该指南非常简单地假设每个人都记得将加载程序组件添加到根模块。
有趣的是没有抛出错误,(因为它是一个指令,而不是一个元素),系统只是假设lazyLoadModule是一个允许的HTML属性? ANyway修正:
@NgModule({
declarations: [
...,
LazyLoadModuleDirective
]
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.