角动态组件AOT问题

时间:2019-06-11 20:03:52

标签: angular typescript angular7 angular2-aot angular-dynamic-components

由于一些业务逻辑,我必须读取动态组件(EntryComponents)的元数据。

要读取元数据,以下是我的方法。

  1. 使用 ComponentFactoryResolver
  2. 读取模块的所有组件
  3. 使用组件名称和特定方法过滤掉类
  4. 创建组件并读取数据
  5. 销毁组件。

const factories = Array.from<any>(this.resolver['_factories'].keys());
console.log(factories); // Logging all the factories

factories.forEach(element => {
  if (element.prototype.registerReportCard) { // checking if this is dynamic component. Because dynamic component will have registerReportCard method in it
    temp.push(element.prototype.constructor.name); // if this is my dynamic component, push the name into another array "tmp".
  }
});

temp.forEach(componentName => { // stored component name from above
    const factoryClass = factories.find( // finding that component which have registerReportCard  method and has name same as iterator.
      item =>
        item.prototype.registerReportCard &&
        item.prototype.constructor.name === componentName
    );
    // component found, obviously.
    const component = this.resolver
      .resolveComponentFactory(factoryClass)
      .create(this.createInjector()); // creating the component and passing in the injector.

    console.log('component', component);

    const componentMeta = component.instance[
      'componentMeta'
    ] as ReportComponentMetaInterface; // Reading the DATA which i need.


    component.destroy(); // destroying the component after reading the data.
  });

createInjector() {
    const staticProvider = [{ provide: [], useValue: '' }];

    return Injector.create(staticProvider);
 }

问题

在开发过程中,工厂名称运行良好,并且与动态组件类相同。

但是在使用ng build --prod构建项目之后。 工厂名称如下 enter image description here

如您所见,首先我在哪里以及为什么收到错误IDK。

第二,工厂类名称相同。因此,相同的动态组件将被加载10次(因为有10个动态组件)。

这是NgModule

@NgModule({


 declarations: [
    DynamicComponentLoaderDirective,
    ContactsCreatedByDayComponent,
    ReportSkeletonComponent,
    SalesPerformanceComponent,
    TopPersonasComponent,
    ContactsOverviewComponent,
    CompaniesRevenueConversionComponent,
    ClosedCompaniesConversionComponent,
    AverageTimeCloseComponent,
    AverageTimeResponseComponent,
    ContactLifecyclePipelineComponent
  ],
  imports: [
    CommonModule,
    MatButtonModule,
    MatProgressSpinnerModule,
    ChartsModule
  ],
  entryComponents: [ContactsCreatedByDayComponent, SalesPerformanceComponent, TopPersonasComponent , ContactsOverviewComponent, CompaniesRevenueConversionComponent, ClosedCompaniesConversionComponent, AverageTimeCloseComponent, AverageTimeResponseComponent, ContactLifecyclePipelineComponent],
  exports: [DynamicComponentLoaderDirective, ReportSkeletonComponent, TopPersonasComponent, ContactsOverviewComponent, CompaniesRevenueConversionComponent, ClosedCompaniesConversionComponent, AverageTimeCloseComponent, AverageTimeResponseComponent, ContactLifecyclePipelineComponent],
  providers: [DashboardReportService]
})
export class DashboardSharedModule {}

我真的不知道为什么会这样。有人可以给我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

-prod标志将缩小作用应用于您的代码,这会导致“ ... constructor.name”以类似于“ a.name”的形式结束。这是导致您出现问题的原因。根本问题是您的代码无法使用最小化,您应该对其进行调整。您可以将构建配置为不进行优化(当前的Angular版本中为angular.json),但是最小化具有其意义,因此您应该尝试找到一种以不同方式提供类名的方法,例如使用包含名称的字符串函数参数可以做到这一点。可以将数据传递给可以在Angular Material上进行比较的entryComponents的另一种实现方式,MatDialogs实际上是获得MAT_DIALOG_DATA的entryComponents,您可以通过注入的方式指定它们:https://material.angular.io/components/dialog