繁体   English   中英

如何在没有路由器的情况下动态延迟加载模块 - Angular 9

[英]How to dynamically lazy load module without router - Angular 9

我有几个我想动态延迟加载的模块,我正在从 v8 升级到 v9,随着 angular 的版本 9,有关模块的逻辑似乎已经改变。 最好的方法是什么?

  1. 没有模块的组件

如果我们想动态地延迟加载一个组件(没有模块),那么我们可以使用与路由相同的模式:

// <ng-template #myContainer></ng-template>    
@ViewChild('myContainer', { read: ViewContainerRef }) container: ViewContainerRef;
  
const { MyLazyComponent } = await import('./path/to/lazy/component');
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(MyLazyComponent);
const { instance } = this.container.createComponent(componentFactory);
  1. 模块

如果组件依赖于其他服务/组件,那么我们需要加载完整的模块。 因为它将被延迟加载(最初未编译)我们需要“手动”运行编译。 它仍然比以前版本 Angular 上使用的技巧更容易。这是一个解决方案。

我们可以创建一个存储模块引用的服务,并将组件加载到容器中(给定模块 ID 和容器引用)。

import { Injectable, Compiler, Injector } from '@angular/core';

@Injectable({
    providedIn: 'root'
})
export class LazyComponentService {

    private componenttRefs = {
        myFirstLazyModuleId: import('../path/to/first/lazy/module/component.module'),
        mySecondLazyModuleId: import('../path/to/second/lazy/module/component.module')
    };

    constructor(
        private compiler: Compiler,
        private injector: Injector,
    ) { }

    async loadComponent(moduleId, container) {

        let ref;
        try {
            const moduleObj = await this.componenttRefs[moduleId];
            const module = moduleObj[Object.keys(moduleObj)[0]];
            const moduleFactory = await this.compiler.compileModuleAsync(module);
            const moduleRef: any = moduleFactory.create(this.injector);
            const componentFactory = moduleRef.instance.resolveComponent();
            ref = container.createComponent(componentFactory, null, moduleRef.injector);
        } catch (e) {
            console.error(e);
        }
        return ref;

    }

}

需要编译模块。 我们通过在每个模块的构造函数中调用 resolveComponentFactory 来实现:

@NgModule({
  imports: [
    MyModules...
  ],
  declarations: [
    MyFirstLazyComponent
  ]
})
export class MyFirstLazyComponentModule {

  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

  public resolveComponent(): ComponentFactory<MyFirstLazyComponent> {
    return this.componentFactoryResolver.resolveComponentFactory(MyFirstLazyComponent);
  }

}

然后魔法出现了,你可以动态地将组件延迟加载到容器中:

  const myFirstLazyComponent = await this.lazyComponentService.loadComponent(myFirstLazyModuleId, containerRef);

我有几个模块想要动态延迟加载,我正在从 v8 升级到 v9,随着 angular 版本 9,有关模块的逻辑似乎已经改变。 最好的方法是什么?

暂无
暂无

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

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