Browse Source

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

pull/11617/head
Igor Kulikov 2 years ago
parent
commit
0d7a6bbaf3
  1. 45
      ui-ngx/src/app/core/services/dynamic-component-factory.service.ts
  2. 2
      ui-ngx/src/app/shared/components/markdown.component.ts

45
ui-ngx/src/app/core/services/dynamic-component-factory.service.ts

@ -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,32 +77,26 @@ export class DynamicComponentFactoryService {
declarations: [comp], declarations: [comp],
imports: moduleImports imports: moduleImports
})(class DynamicComponentInstanceModule extends DynamicComponentModule {}); })(class DynamicComponentInstanceModule extends DynamicComponentModule {});
const module = this.compiler.compileModuleSync(dynamicComponentInstanceModule);
let moduleRef: NgModuleRef<any>;
try { try {
const module = this.compiler.compileModuleSync(dynamicComponentInstanceModule); moduleRef = module.create(this.injector);
let moduleRef: NgModuleRef<any>; // eslint-disable-next-line
try { comp[ɵNG_COMP_DEF];
moduleRef = module.create(this.injector); } catch (e) {
} catch (e) { this.compiler.clearCacheFor(module.moduleType);
this.compiler.clearCacheFor(module.moduleType); ɵresetCompiledComponents();
throw e; throw e;
}
this.dynamicComponentModulesMap.set(comp, {
moduleRef,
moduleType: module.moduleType
});
return of( {
componentType: comp,
componentModuleRef: moduleRef
});
} catch (error) {
if (compileAttempt === 1) {
ɵresetCompiledComponents();
return this.createDynamicComponent(componentType, template, modules, preserveWhitespaces, ++compileAttempt, styles);
} else {
console.error(error);
throw error;
}
} }
this.dynamicComponentModulesMap.set(comp, {
moduleRef,
moduleType: module.moduleType
});
return of( {
componentType: comp,
componentModuleRef: moduleRef
});
}) })
); );
} }

2
ui-ngx/src/app/shared/components/markdown.component.ts

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

Loading…
Cancel
Save