UI: Improve dynamic components compilation - compile component in place to correctly handle template compile errors.

This commit is contained in:
Igor Kulikov 2024-09-10 18:01:49 +03:00
parent bbc3e904c8
commit 0d7a6bbaf3
2 changed files with 20 additions and 27 deletions

View File

@ -22,7 +22,7 @@ import {
NgModule, NgModule,
NgModuleRef, NgModuleRef,
OnDestroy, OnDestroy,
Type, Type, ɵNG_COMP_DEF,
ɵresetCompiledComponents ɵresetCompiledComponents
} from '@angular/core'; } from '@angular/core';
import { from, Observable, of } from 'rxjs'; import { from, Observable, of } from 'rxjs';
@ -64,7 +64,6 @@ export class DynamicComponentFactoryService {
template: string, template: string,
modules?: Type<any>[], modules?: Type<any>[],
preserveWhitespaces?: boolean, preserveWhitespaces?: boolean,
compileAttempt = 1,
styles?: string[]): Observable<DynamicComponentData<T>> { styles?: string[]): Observable<DynamicComponentData<T>> {
return from(import('@angular/compiler')).pipe( return from(import('@angular/compiler')).pipe(
mergeMap(() => { mergeMap(() => {
@ -78,13 +77,16 @@ export class DynamicComponentFactoryService {
declarations: [comp], declarations: [comp],
imports: moduleImports imports: moduleImports
})(class DynamicComponentInstanceModule extends DynamicComponentModule {}); })(class DynamicComponentInstanceModule extends DynamicComponentModule {});
try {
const module = this.compiler.compileModuleSync(dynamicComponentInstanceModule); const module = this.compiler.compileModuleSync(dynamicComponentInstanceModule);
let moduleRef: NgModuleRef<any>; let moduleRef: NgModuleRef<any>;
try { try {
moduleRef = module.create(this.injector); moduleRef = module.create(this.injector);
// eslint-disable-next-line
comp[ɵNG_COMP_DEF];
} catch (e) { } catch (e) {
this.compiler.clearCacheFor(module.moduleType); this.compiler.clearCacheFor(module.moduleType);
ɵresetCompiledComponents();
throw e; throw e;
} }
this.dynamicComponentModulesMap.set(comp, { this.dynamicComponentModulesMap.set(comp, {
@ -95,15 +97,6 @@ export class DynamicComponentFactoryService {
componentType: comp, componentType: comp,
componentModuleRef: moduleRef componentModuleRef: moduleRef
}); });
} catch (error) {
if (compileAttempt === 1) {
ɵresetCompiledComponents();
return this.createDynamicComponent(componentType, template, modules, preserveWhitespaces, ++compileAttempt, styles);
} else {
console.error(error);
throw error;
}
}
}) })
); );
} }

View File

@ -160,7 +160,7 @@ export class TbMarkdownComponent implements OnChanges {
}, },
template, template,
compileModules, compileModules,
true, 1, styles true, styles
).subscribe((componentData) => { ).subscribe((componentData) => {
this.tbMarkdownInstanceComponentType = componentData.componentType; this.tbMarkdownInstanceComponentType = componentData.componentType;
const injector: Injector = Injector.create({providers: [], parent: this.markdownContainer.injector}); const injector: Injector = Injector.create({providers: [], parent: this.markdownContainer.injector});