Lazy load module in angular 8

前端 未结 2 1627
一整个雨季
一整个雨季 2020-12-30 16:41

I have a dashboard app where I was lazy loading widgets (not tied to a route).

I was doing this by defining an object {name: string, loadChildren: string}

相关标签:
2条回答
  • 2020-12-30 16:57

    In Angular 8 the result of loadChildren function is either Promise of NgModule type in JIT mode or Promise of NgModuleFactory in AOT mode.

    With this in mind you can rewrite your service as follows:

    import { 
        Injectable, Compiler, Injector, Type, 
        ViewContainerRef, ComponentFactoryResolver,
        NgModuleFactory, Inject 
    } from '@angular/core';
    
    @Injectable()
    export class LazyLoaderService {
    
      constructor(private injector: Injector,
        private compiler: Compiler,
        @Inject(LAZY_WIDGETS) private lazyWidgets: 
           { [key: string]: () => Promise<NgModuleFactory<any> | Type<any>> }) { }
    
    
      async load(name: string, container: ViewContainerRef) {
        const ngModuleOrNgModuleFactory = await this.lazyWidgets[name]();
     
        let moduleFactory;
    
        if (ngModuleOrNgModuleFactory instanceof NgModuleFactory) {
          // aot mode
          moduleFactory = ngModuleOrNgModuleFactory;
        } else {
          // jit mode
          moduleFactory = await this.compiler.compileModuleAsync(ngModuleOrNgModuleFactory);
        }
    
        const entryComponent = (<any>moduleFactory.moduleType).entry;
        const moduleRef = moduleFactory.create(this.injector);
    
        const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
    
        const comp = container.createComponent(compFactory);
      }   
    }
    

    Stackblitz Example

    Tip: Always look at the source code when you're in doubt

    • https://github.com/angular/angular/blob/72ecc453639eae017f75653c9004adc406ed2ee6/packages/router/src/router_config_loader.ts#L46-L59

    • https://github.com/angular/angular/blob/32886cf9ace539e14e2b387cd8afb10715c8d3de/aio/src/app/custom-elements/elements-loader.ts#L56-L68

    0 讨论(0)
  • 2020-12-30 17:07

    It seems that when using Router, lazyWidgets const should have not name but path property:

    export const lazyWidgets: { path: string, loadChildren: () => .....
    

    Otherwise you'll get error:

    Invalid configuration of route '': routes must have either a path or a matcher specified

    0 讨论(0)
提交回复
热议问题