由于一些业务逻辑,我必须读取动态组件(EntryComponents)的元数据。
要读取元数据,以下是我的方法。
- 使用ComponentFactoryResolver读取模块的所有组件
- 使用组件名称和特定方法过滤掉类
- 创建组件并读取数据
- 销毁组件。
.
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 {}
我真的不知道为什么会这样。有人可以帮我指明正确的方向吗?
最佳答案
--prod 标志对代码进行缩小,导致“...constructor.name”最终成为“a.name”之类的内容。这就是你的问题的原因。根本问题是您的代码无法在缩小的情况下工作,您应该对其进行调整。您可以配置您的构建不进行优化(当前 Angular 版本中的 angular.json ),但缩小有其意义,因此您应该尝试找到一种以不同方式提供类名的方法,例如使用包含名称的字符串函数参数可以做到这一点。将数据传递到entryComponents的另一种实现,您可以在Angular Material中进行比较,MatDialogs实际上是entryComponents,它获取MAT_DIALOG_DATA,您可以通过注入(inject)以您想要的方式指定它:https://material.angular.io/components/dialog .
关于Angular 动态组件 AOT 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56551008/