【问题标题】:Angular Dynamic Components AOT IssueAngular 动态组件 AOT 问题
【发布时间】:2019-10-26 07:22:29
【问题描述】:

由于某些业务逻辑,我不得不读取动态组件(EntryComponents)的元数据。

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

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

.

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 构建项目之后。 工厂名称如下

如您所见,首先我在哪里以及为什么会收到错误 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 {}

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

【问题讨论】:

  • 您能否提供您的 NgModule 声明组件的位置。
  • 嗨,我已经用 NgModule 更新了我的问题,请检查。我正在导出组件,因为这是共享模块,并且此共享模块正在导入到我要显示动态组件的其他模块中。

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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2018-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 2017-10-01
    • 2018-07-24
    • 2020-05-15
    • 2018-04-09
    相关资源
    最近更新 更多