Angular Ivy:读取模块提供程序

时间:2019-04-08 11:15:36

标签: angular angular-ivy

我正试图在Angular Ivy中延迟加载组件

import("./app/products/products.module").then((module) => {
  console.log(module.ProductsModule.ngInjectorDef.providers);
});

模块代码

import { CommonModule } from "@angular/common";
import { NgModule } from "@angular/core";
import { LazyComponent } from "./lazy/lazy.component";

@NgModule({
  declarations   : [LazyComponent],
  imports        : [
    CommonModule
  ],
  entryComponents: [
    LazyComponent
  ],
  providers      : [
    {
      provide : "components",
      useValue: {
        lazy: LazyComponent,
      }
    }
  ]
})
export class ProductsModule {
}

我可以使用module.ProductsModule.ngInjectorDef.providers访问提供商,但我正在寻找更好的方法

也许像module.ProductsModule.ngInjectorDef.get("components")

1 个答案:

答案 0 :(得分:1)

Ivy具有一个名为createInjector的私有函数,它在当前API中与theta一起公开,但是稍后在Ivy稳定后会公开。

假设您有这样的代码:

@NgModule({
  declarations: [LazyComponent],
  providers: [
    {
      provide: 'components',
      useValue: {
        lazy: LazyComponent
      }
    }
  ],
  entryComponents: [LazyComponent]
})
export class LazyModule {
  static getLazyComponents: () => { lazy: typeof LazyComponent };

  constructor(injector: Injector) {
    LazyModule.getLazyComponents = () => injector.get('components');
  }
}

让我们通过动态导入延迟加载LazyModule

import { ɵcreateInjector as createInjector, Injector } from '@angular/core';

export class AppComponent {
  constructor(injector: Injector) {
    import('./lazy/lazy.module').then(({ LazyModule }) => {
      createInjector(LazyModule, injector);
      console.log(LazyModule.getLazyComponents());
    });
  }
}

但是使用这种方法-您可以延迟加载模块。如果您想延迟加载组件-您可以不使用模块就可以加载它,请假设此LazyComponent位于lazy.component.ts文件内:

@Component({
  selector: 'app-lazy',
  template: `
    <h1>I am lazy</h1>
  `
})
export class LazyComponent {}

您可以使用动态导入来加载此组件+ renderComponent函数:

import { ɵrenderComponent as renderComponent, Injector } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <app-lazy></app-lazy>
  `
})
export class AppComponent {
  constructor(injector: Injector) {
    import('./lazy.component').then(({ LazyComponent }) => {
      renderComponent(LazyComponent, {
        injector,
        host: 'app-lazy'
      });
    });
  }
}

一个注意事项-惰性组件没有生命周期! constructor将被调用,但不会被ngOnInitngOnDestroy等钩子所吸引。

回到有关延迟模块的问题-您可能希望公开那些延迟组件的组件工厂,如下所示:

export class LazyModule {
  static getComponentFactories: () => {
    lazy: ComponentFactory<LazyComponent>;
  };

  constructor(resolver: ComponentFactoryResolver) {
    LazyModule.getComponentFactories = () => ({
      lazy: resolver.resolveComponentFactory(LazyComponent)
    });
  }
}

如果您不想使用静态函数,则可以声明实例方法:

export class LazyModule {
  constructor(private resolver: ComponentFactoryResolver) {}

  public getComponentFactories() {
    return {
      lazy: this.resolver.resolveComponentFactory(LazyComponent)
    };
  }
}

然后获取此模块的实例:

export class AppComponent {
  constructor(private injector: Injector) {
    import('./lazy/lazy.module').then(({ LazyModule }) => {
      const injector = createInjector(LazyModule, this.injector);
      const lazyModule = injector.get(LazyModule);
      console.log(lazyModule.getComponentFactories());
    });
  }
}