繁体   English   中英

Angular 8 CLI:如何使用提供程序延迟加载不可路由的功能模块

[英]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>

结果是:

  1. 如果我使用没有包装器对象的SystemJsNgModuleLoader,则Chunking工作 (webpack报告它构建了一个路径到组件my-module.ts )在开发工具中我得到SystemJsNgModuleLoader的NullinjectorError

  2. 如果我直接在提供程序中使用SystemJsNgModuleLoader我在开发控制台中没有出错。 Chunking也有效。 但是在网络控制台中, 模块永远不会被加载 ,即使我直接在app控制器中设置showModule = true ...

上面的例子很有效。 该指南非常简单地假设每个人都记得将加载程序组件添加到根模块。

有趣的是没有抛出错误,(因为它是一个指令,而不是一个元素),系统只是假设lazyLoadModule是一个允许的HTML属性? ANyway修正:

@NgModule({
  declarations: [
    ...,
    LazyLoadModuleDirective
  ]
  ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM