首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何编译运行时生成的Angular8代码?

如何编译运行时生成的Angular8代码?
EN

Stack Overflow用户
提问于 2020-04-10 09:58:27
回答 1查看 1.9K关注 0票数 5

我在运行时创建角代码,特别是,我使用SVG库来创建一个包含角代码指令(如(click)='myMethod()' )的矢量图形,然后调用我在SVG封装组件中静态定义的方法。在运行时生成时,我需要编译创建的模板并将其添加到组件中。我在这个职位的帮助下用Range3实现了这样的代码,这非常麻烦。我试图在一个角8应用程序中复制旧代码:

代码语言:javascript
运行
复制
private addComponent(template: string) {

    @Component({template: template + ' <div #target></div>'})
    class TemplateComponent {

      @ViewChild('target', {static: false, read: ViewContainerRef}) public target;

      constructor() {
      }

      public myMethod() {
        // do something     
      }
    }

    @NgModule({declarations: [TemplateComponent]})
    class TemplateModule {
      @ViewChild('target', {static: false, read: ViewContainerRef}) public target;
    }

    // ERROR in next line:
    const mod = this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
    const factory = mod.componentFactories.find((comp) =>
        comp.componentType === TemplateComponent
    );
    this.container.createComponent(factory);
}

但现在却失败了

错误:运行时编译器未在Compiler._throwError (core.js:38932)加载

一方面,我不知道为什么会发生这种错误。我在互联网上发现的所有东西都是关于函数语法在惰性模块加载中的。另一方面,我想知道,如果五个角的主要版本后,有另一种方式来做。我读过关于门户的文章,但它似乎是动态加载静态模板的,而不是动态生成的未编译模板。期待有人指点我的方向。

Post Scriptum:为能够提供基本运行代码片段的Bounty添加一个Bounty,以便在AoT模式下获取角v9。它必须包含运行时编译的模板(例如,来自字符串变量),其中包含关联组件中的方法调用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-17 22:32:50

在默认情况下,JIT编译器被排除在AOT捆绑包之外,因此您必须手动包含它。您需要安装包@angular/platform-browser-dynamic并将Compiler提供程序添加到应用程序模块中。例如:

代码语言:javascript
运行
复制
import { NgModule, COMPILER_OPTIONS, CompilerFactory, Compiler } from '@angular/core';
import { JitCompilerFactory } from '@angular/platform-browser-dynamic';

@NgModule({
  providers: [
    { provide: COMPILER_OPTIONS, useValue: {}, multi: true },
    { provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS] },
    { provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory] }
  ]
})
export class AppModule { }

export function createCompiler(compilerFactory: CompilerFactory) {
  return compilerFactory.createCompiler();
}

然后,您还必须对代码进行一些小的更改,因为不能使用@Component装饰器将模板设置为变量,这会导致编译错误。必须在代码中动态运行装饰器。

下面是通过更改更新的方法:

代码语言:javascript
运行
复制
private addComponent(template: string) {
  class TemplateComponent {

    @ViewChild('target', {static: false, read: ViewContainerRef}) public target;

    constructor() {
    }

    public myMethod() {
      // do something     
    }
  }

  class TemplateModule {
    @ViewChild('target', {static: false, read: ViewContainerRef}) public target;
  }

  const componentType = Component({template: template + '<div #target></div>'})(TemplateComponent)

  const componentModuleType = NgModule({declarations: [componentType]})(TemplateModule)

  const mod = this.compiler.compileModuleAndAllComponentsSync(componentModuleType);
  const factory = mod.componentFactories.find((comp) =>
      comp.componentType === componentType
  );
  this.container.createComponent(factory);
}

我还创建了一个StackBlitz样品,您可以在这里看到它的工作。

有关如何执行此操作的更详细示例,请使用完整示例检查此角AOT动态组件GitHub库

我在关于动态加载组件模板的角度GitHub问题里发现了这个。由于您使用这个,它可能是好的,您跟踪问题,以了解最新的发展。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61137899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档