Шаблон должен содержать строковую ошибку в Angular 9 - PullRequest
1 голос
/ 15 апреля 2020

Я пытаюсь реализовать шаблон динамического c в приложении Angular 9, основанный на этом примере [https://plnkr.co/edit/yftZxS45CQpwi3uIM4BV?preview] [1]

В Angular 7 он работает нормально, но в 9 он дает ошибки:

ERROR in src/app/html-outlet.ts:32:19 - error NG1010: template must be a string

32         template: html
                     ~~~~
src/app/html-outlet.ts:38:24 - error NG6001: The class 'DynamicHtmlComponent' is listed in the declarations of 
the NgModule 'DynamicHtmlModule', but is not a directive, a component, or a pipe. Either remove it from the 
NgModule's declarations, or add an appropriate Angular decorator.

38         declarations: [DynamicHtmlComponent]
                          ~~~~~~~~~~~~~~~~~~~~

  src/app/html-outlet.ts:34:13
    34       class DynamicHtmlComponent  {};
                   ~~~~~~~~~~~~~~~~~~~~
    'DynamicHtmlComponent' is declared here.

app.module.ts

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

import { AppComponent } from './app.component';
import { HtmlOutlet } from './html-outlet';
@NgModule({
  declarations: [
    AppComponent, HtmlOutlet
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'htmloutlet';
  html = "Test dynamic component {{ 1 + 1 }}";
}

app. component. html

<div>
  <h2>Hello</h2>
  <html-outlet [html]="html"></html-outlet>
</div>

html -outlet

import {
    NgModule,
    Component,
    Directive,
    Input,
    ComponentRef,
    Compiler,
    ViewContainerRef
  } from '@angular/core';

  import { CommonModule } from '@angular/common';

  @Directive({ selector: 'html-outlet' })
  export class HtmlOutlet {
    @Input() html: string;
    cmpRef: ComponentRef<any>;

    constructor(private vcRef: ViewContainerRef, private compiler: Compiler) { }

    ngOnChanges() {
      const html = this.html;
      if (!html) return;

      if(this.cmpRef) {
        this.cmpRef.destroy();
      }

      @Component({
        selector: 'dynamic-comp',
        template: html
      })
      class DynamicHtmlComponent  {};

       @NgModule({
        imports: [CommonModule ],
        declarations: [DynamicHtmlComponent]
      })
      class DynamicHtmlModule {}

      this.compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
        .then(factory => {
          const moduleRef = factory.ngModuleFactory.create(this.vcRef.parentInjector);

          const compFactory = factory.componentFactories.find(x => x.componentType === DynamicHtmlComponent);
          const cmpRef = this.vcRef.createComponent(compFactory, 0, moduleRef.injector);
        });
    }

    ngOnDestroy() {
      if(this.cmpRef) {
        this.cmpRef.destroy();
      }    
    }
  }

my Angular version

Angular CLI: 9.1.1
Node: 10.15.3
OS: win32 x64

Angular: 9.1.1
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.901.1
@angular-devkit/build-angular     0.901.1
@angular-devkit/build-optimizer   0.901.1
@angular-devkit/build-webpack     0.901.1
@angular-devkit/core              9.1.1
@angular-devkit/schematics        9.1.1
@ngtools/webpack                  9.1.1
@schematics/angular               9.1.1
@schematics/update                0.901.1
rxjs                              6.5.5
typescript                        3.8.3
webpack                           4.42.0

Обсуждение проблемы, как это: ( https://github.com/angular/angular/issues/35584)

Скажите, пожалуйста, как мне избежать этой проблемы?

...