Angular 6/7 AOT:动态模板渲染-加载模块的JitCompiler

Lyc*_*zos 6 jit dynamic aot angular

我在通过API响应“即时”构建模板时遇到了问题,但仅在AoT构建中存在问题。

我从后端收到了这样的回复:

<h1>Title...</h1> 
<some-component></some-componen> 
<p>other content</p>
Run Code Online (Sandbox Code Playgroud)

我想像常规的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, []);
              });
          }


        }
Run Code Online (Sandbox Code Playgroud)

因此,我将整个数据传递到content输入中,然后通过compileModuleAndAllComponentsAsync方法(https://angular.io/api/core/Compiler#compilemoduleandallcomponentssync)编译所有组件,并且所有工作都在JIT build中进行

我想在AoT编译中完成这项工作,因为现在我得到一个错误: Runtime Compiler is not loaded在示例代码上使用AoT进行构建时

我也试图在app.module.ts中提供编译器,providers[]但它也不起作用:

export function createCompiler(compilerFactory: CompilerFactory) {
  return compilerFactory.createCompiler();
}    
Run Code Online (Sandbox Code Playgroud)

    {provide: COMPILER_OPTIONS, useValue: {}, multi: true},
    {provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]},
    {provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory]},
Run Code Online (Sandbox Code Playgroud)

我的问题:有没有办法在JIT编译器中包含延迟加载的模块以访问其方法?

我发现了一些相关问题,但没有答案:

在Angular 5和AOT-Build中使用@angular编译器时出错

编辑15.01.2019 这是stackblitz.com上的工作JIT示例,具有插值和数据绑定测试:https : //stackblitz.com/github/lyczos/angular-dynamic-html-renderer

Nar*_*arm 3

首先,我为写这个作为答案而道歉,但它太长了,无法正确作为评论。

可以做你所要求的事情。事实上,我今年在 ng-conf 上确实提出了这个问题。在 Max Koretskyi(又名 AngularinDepth.com 的“ng-wizard”作者)就这个主题举办过一次会议后,我与他进行了交谈。

我必须警告你,尽管他提供的解决方案非常复杂、hacky,你不能指望它不会在未来的 Angular 版本中出现问题,因为你想要完成的任务违背了 Angular 框架,而这正是 Angular 团队的目标正在试图阻止人们做某事。实际上,尝试维护这将是一场噩梦,任何新的开发人员可能都会竭尽全力试图理解我所做的事情。哎呀,如果一年多后我回头看的话,我可能都不知道自己做了什么。

最终,我决定放弃 AOT 并使用 JIT 部署我的应用程序,从那时起我就没有后悔过我的决定。如果您决定确实想进一步追求这一点,我建议您联系 Max。据我在 ng-conf 了解到的情况来看,他是一个非常友好的人,他公开邀请人们在有疑问时与他联系。希望有帮助,祝你好运!:)