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

标签 angular lazy-loading

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

最佳答案

  • 没有模块的组件

  • 如果我们想动态地延迟加载一个组件(没有模块),那么我们可以使用与路由相同的模式:
    // <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);
    
  • 模块

  • 如果组件依赖于其他服务/组件,那么我们需要加载完整的模块。因为它将被延迟加载(最初未编译),我们需要“手动”运行编译。它仍然比以前版本的 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);
    

    关于angular - 如何在没有路由器的情况下动态延迟加载模块 - Angular 9,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60971689/

    相关文章:

    c# - 复杂类型引用的 EagerLoad 实体

    css - 如何以 Angular 更改下拉框的高度?

    angular - NgRx - 从后端获取错误验证并传递给组件

    angular - 防止 mat-option 选择 if 条件

    javascript - 在页面的其余部分完成加载后延迟加载 html5 视频

    javascript - Handlebars.js:渲染大数据而不阻塞 UI – 使用 setTimeout() 延迟或延迟加载?

    hibernate - 数据传输对象和事务服务方法

    node.js - IIS 中 Angular 2 应用程序的应用程序动态 - Node.js 代理安装和配置

    javascript - 什么是关于 TypeScript 的猴子补丁?

    Angular 6/7 辅助导出按路线导航 - 清除主导出,但不应该