简体   繁体   English

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

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

I have several modules that I want to lazy load dynamically, I am upgrading from v8 to v9, with the version 9 of angular the logic concerning modules seems to have changed.我有几个我想动态延迟加载的模块,我正在从 v8 升级到 v9,随着 angular 的版本 9,有关模块的逻辑似乎已经改变。 What is the best way of doing it?最好的方法是什么?

  1. Component with no module没有模块的组件

If we want to lazy-load a component dynamically (with no module), then we can use the same pattern as with routes:如果我们想动态地延迟加载一个组件(没有模块),那么我们可以使用与路由相同的模式:

// <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. Modules模块

If the component depends on other services / components then we need to load the full module.如果组件依赖于其他服务/组件,那么我们需要加载完整的模块。 Because it will be lazy loaded (not compiled initially) we need to run the compilation "manually".因为它将被延迟加载(最初未编译)我们需要“手动”运行编译。 It is still easier than previous tricks used on previous versions of Angular. Here is a solution.它仍然比以前版本 Angular 上使用的技巧更容易。这是一个解决方案。

We can create a service that store module references, and load the component into a container (given a module ID and a container reference).我们可以创建一个存储模块引用的服务,并将组件加载到容器中(给定模块 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;

    }

}

Modules need to be compiled.需要编译模块。 We do it by calling resolveComponentFactory inside each module's constructor:我们通过在每个模块的构造函数中调用 resolveComponentFactory 来实现:

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

  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

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

}

And then the magic is up, you can dynamically lazy load a component to a container:然后魔法出现了,你可以动态地将组件延迟加载到容器中:

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

I have several modules that I want to lazy load dynamically, I am upgrading from v8 to v9, with the version 9 of angular the logic concerning modules seems to have changed.我有几个模块想要动态延迟加载,我正在从 v8 升级到 v9,随着 angular 版本 9,有关模块的逻辑似乎已经改变。 What is the best way of doing it ?最好的方法是什么?

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

相关问题 如何在没有CLI的情况下延迟加载Angular模块? - How to lazy load Angular module without CLI? 没有路由器的Angular延迟加载模块 - Angular lazy loading module without router 角度路由器延迟加载依赖模块的入口组件如何工作,但自定义延迟加载模块没有问题 - How angular router lazy loading dependent modules entryComponents works without issue but not the custom lazy loaded module Angular Router:将模块作为延迟加载模块的子级加载 - Angular Router: Load module as child of lazy loaded modules angular直接加载带有嵌套路由器插座的惰性模块 - angular directly load a lazy module with nested router-outlet 带有延迟加载模块和子路由的Angular 7路由器&#39;**&#39;通配符不起作用? - Angular 7 router '**' wildcard with lazy load module and child routes not working? 具有Angular4中具有动态路由的Router Guard的延迟加载模块 - Lazy load module with Router Guard with dynamic routes in Angular4 如何在角的延迟加载模块中延迟加载模块? - How to lazy load module in lazy loaded module in angular? 延迟加载模块,角度为8 - Lazy load module in angular 8 使用 Angular 路由器的模块延迟加载 - Module Lazy Loading with the Angular Router
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM