簡體   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