Как динамически лениво загрузить модуль Angular 9 - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть несколько модулей, которые я хочу динамически загружать, я обновляюсь с v8 до v9, с версией 9 angular логика c относительно модулей, похоже, изменилась. Каков наилучший способ сделать это?

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

Как здесь объявлено https://update.angular.io/#8 .0: 9.0l2 Вы должны использовать динамический c импорт:

const routes: Routes = [{
  path: 'lazy',
  // The new import() syntax
  loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}];

Строковый синтаксис для loadChildren устарел.

0 голосов
/ 07 апреля 2020
  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);
Модули

Если компонент зависит от других служб / компонентов, нам нужно загрузить модуль, для этого нам нужно указать angular для его компиляции. Это все еще проще, чем предыдущие приемы, использованные в предыдущих версиях Angular. Вот решение.

Мы можем создать сервис, который будет хранить ленивые ссылки на модули и динамически лениво загружать модуль (с учетом идентификатора модуля и ссылки на контейнер).

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;

    }

}

Модули то, что должно быть загружено с отложенной загрузкой, тогда необходимо вызвать метод resolComponentFactory, это означает добавление службы к модулю следующим образом:

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

  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

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

}

И тогда волхвы c работают, вы можете динамически лениво загрузить компонент к контейнеру:

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