本文介绍了角动态组件AOT问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Due to some business logic, I have to read the meta data of dynamic components(EntryComponents).

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

To read the meta data, following is my approach.

  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);
 }

问题

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

During development, factories names are working fine and are same as the dynamic component class.

但是在使用ng build --prod构建项目之后.工厂名称如下

But after building the project using ng build --prod.The factories names are as follows

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

As you can see, first im getting an error IDK where and why.

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

Secondly, the factories class names are same. Hence same dynamic component is being loaded 10 times (because there are 10 dynamic components).

这是NgModule

Here is the 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 {}

我真的不知道为什么会这样.有人可以让我朝正确的方向前进吗?

I really dont know why is this happening. Can someone please put me in right direction?

推荐答案

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

The --prod flag applies minification to your code which causes "...constructor.name" to end up as something like "a.name". This is the cause of your problem. The root problem is that your code won't work with minification and you should adapt it. You can configure your build not to optimize (angular.json in the current angular version), but minification has its sense, so you should try to find a way to provide the class name differently, e.g. with a string function param containing the name you can do that. Another implementation for passing data to entryComponents you can maybe compare at Angular Material, the MatDialogs are actually entryComponents which get MAT_DIALOG_DATA which you can specify in the way you want by injection: https://material.angular.io/components/dialog.

这篇关于角动态组件AOT问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 16:09