在AOT模式下无法在动态生成的Angular模块中的动态生成的组件的模板中使用异步管道

时间:2019-04-17 20:57:18

标签: angular angular-aot angular-dynamic-components angular-compiler

免责声明:此问题是受Medium上“ Here is what you need to know about dynamic components in Angular”帖子的启发。

作者在那里展示了如何动态地生成模块和组件,将后者放入前者,动态地编译模块,获得组件工厂,并通过ViewContainerRef使用它来生成组件

这在基本设置中很好用。

现在让我们假设我们要动态生成一个组件,但是这次是使用使用async管道的模板。

下一步,我们需要在生产环境中使用此工具,这意味着两件事:

由于没有Angular编译器,因此我们可以在应用程序根模块中为jit compiler的Compiler令牌提供实例。

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import {Compiler, NgModule} from '@angular/core';

import {AppComponent } from './app.component';
import {JitCompilerFactory} from '@angular/platform-browser-dynamic';

export function jitCompiler() {
  /*
   * Cast JitCompilerFactory to any because
   * jit compiler factory constructor does not
   * accept any arguments according to the @angular/platform-browser-dynamic/src/compiler_factory.d.ts
   */
  const klass = (JitCompilerFactory as any);
  return new klass([]).createCompiler([
    {
      useJit: true
    }
  ]);
}

@NgModule({
  declarations: [
    AppComponent
  ],
  providers: [
    {
      provide: Compiler,
      useFactory: jitCompiler
    }
  ],
  imports: [
    BrowserModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import {
  AfterViewInit,
  ChangeDetectionStrategy,
  Compiler,
  Component,
  NgModule,
  ViewContainerRef
} from '@angular/core';
import {Subject} from 'rxjs';
import {CommonModule} from '@angular/common';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent implements AfterViewInit {
  constructor(
    private readonly compiler: Compiler,
    private readonly vcr: ViewContainerRef
  ) {}
  ngAfterViewInit() {
    const template = '<span>Hello, {{text$ }}</span>';
    const cmp = Component({
      template
    })(class DynamicComponent {
      text$: Subject<string>;
    });

    const module = NgModule({
      declarations: [cmp],
      imports: [CommonModule],
      providers: []
    })(class DynamicModule {});

    this.compiler.compileModuleAndAllComponentsAsync(module)
      .then(compiledModule => {
        const dynamicComponent = this.vcr.createComponent(compiledModule.componentFactories[0]);

        const sub = new Subject();
        sub.next('World!');
        dynamicComponent.instance.text$ = sub;

        // Just to simulate some server updates
        setTimeout(() => dynamicComponent.instance.text$.next('Another'), 3e3);
      });
  }
}

如果运行该代码并打开DevTools,则会看到以下错误:

  

错误错误:模块导入了意外的值'function(){}'   '功能(){}'。请添加@NgModule批注。

仅在开发模式下会发生此问题。 Angular版本是7.2.0。

出现问题-要使其在AOT模式下工作必须做什么?

0 个答案:

没有答案