问题
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.
- Read all components of a module using ComponentFactoryResolver
- Filter out classes using Component name and specific method
- Create the component and read the data
- Destroy the component.
.
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);
}
THE PROBLEM
During development, factories names are working fine and are same as the dynamic component class.
But after building the project using ng build --prod. The factories names are as follows
As you can see, first im getting an error IDK where and why.
Secondly, the factories class names are same. Hence same dynamic component is being loaded 10 times (because there are 10 dynamic components).
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?
回答1:
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.
来源:https://stackoverflow.com/questions/56551008/angular-dynamic-components-aot-issue