У меня проблема со сборкой шаблонов "на лету" из ответа API, но только в сборке AoT.
Я получил от бэкэнда такой ответ:
<h1>Title...</h1>
<some-component></some-componen>
<p>other content</p>
И яхочу разобрать это как обычный шаблон Angular.
Упрощенный код моего компонента выглядит следующим образом:
import {
Compiler,
Component,
ComponentFactory,
ComponentRef,
Injector,
Input,
NgModule,
OnChanges,
OnDestroy,
OnInit,
ViewContainerRef
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
export async function createComponentFactory(compiler: Compiler, metadata: Component): Promise> {
const cmpClass = class DynamicComponent {
};
const decoratedCmp = Component(metadata)(cmpClass);
// IMPORT ALL MODULES HERE!!!
@NgModule({imports: [CommonModule, RouterModule], declarations: [decoratedCmp]})
class DynamicHtmlModule {
}
const moduleWithComponentFactory = await compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule);
return moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp);
}
@Component({
selector: 'html-renderer',
templateUrl: './html-renderer.component.html',
styleUrls: ['./html-renderer.component.scss']
})
export class HtmlRendererComponent implements OnInit, OnChanges, OnDestroy {
@Input() content: string;
cmpRef: ComponentRef;
constructor(private vcRef: ViewContainerRef, private compiler: Compiler) { }
ngOnInit(): void {
console.log('init...')
console.log(this.compiler)
}
ngOnDestroy() {
if (this.cmpRef) {
this.cmpRef.destroy();
}
}
ngOnChanges() {
const html = this.content;
if (!html) { return; }
if (this.cmpRef) {
this.cmpRef.destroy();
}
const compMetadata = new Component({
selector: 'dynamic-selector',
template: this.content,
});
createComponentFactory(this.compiler, compMetadata)
.then(factory => {
const injector = Injector.create({providers: [], parent: this.vcRef.injector});
this.cmpRef = this.vcRef.createComponent(factory, 0, injector, []);
});
}
}
Итак, я передаю целые данные на вход content
, затем компилирую все компонентычерез compileModuleAndAllComponentsAsync
метод (https://angular.io/api/core/Compiler#compilemoduleandallcomponentssync) и все работает в сборке JIT .
Я хочу получить эту работу в компиляции AoT, потому что теперь я получаю ошибку: Runtime Compiler is not loaded
при сборке с AoT на примере кода
Я также пытался предоставить компилятор в приложении.module.ts в providers[]
как этот, но он тоже не работает:
export function createCompiler(compilerFactory: CompilerFactory) {
return compilerFactory.createCompiler();
}
{provide: COMPILER_OPTIONS, useValue: {}, multi: true},
{provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]},
{provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory]},
Мой вопрос: есть ли способ включить загруженный ленивый модуль с JIT-компилятором дляполучить доступ к его методам?
Я нашел несколько связанных вопросов, но ответа нет:
Ошибка при использовании @angular компилятора в Angular 5 и AOT-Build
РЕДАКТИРОВАТЬ 15.01.2019 Вот рабочий пример JIT на stackblitz.com с тестом интерполяции и привязки данных: https://stackblitz.com/github/lyczos/angular-dynamic-html-renderer