Как скомпилировать компонент Angular в строку HTML со всеми привязками

Как скомпилировать компонент Angular в строку HTML со всеми привязками

20 декабря 2022 г.

Обычный вариант использования для компиляции компонентов Angular в строки HTML:

  • Формирование внешнего интерфейса PDF с заданным HTML
  • ПЕЧАТЬ HTML
  • Нативные подключаемые модули JS, которым требуется HTML в виде строки.

==К сожалению, в Angular нет открытого метода для компиляции компонента Angular в строку HTML==. Но благодаря ComponentFactoryResolver в Angular мы можем создать обходной путь для этого. Используя ComponentFactoryResolver, мы можем динамически отображать требуемый компонент в шаблон, а затем мы получаем доступ к nativeElement.innerHTML из componentRef.

Здесь следует отметить одну вещь: мы использовали import { asyncScheduler } from 'rxjs'; для получения HTML со всеми привязками. Если мы не настроим этот планировщик, привязка данных не будет доступна в анализируемом HTML.

app.component.ts

import {
  Component,
  ComponentFactory,
  ComponentFactoryResolver,
  ViewChild,
  ViewContainerRef,
} from '@angular/core';
import { asyncScheduler } from 'rxjs';
import { PdfHtmlComponent } from './pdf-html.component';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  @ViewChild('pdfHtml', { read: ViewContainerRef }) container;

  constructor(private resolver: ComponentFactoryResolver) {}

  getPDFHtml() {
    this.container.clear();
    const factory: ComponentFactory<any> =
      this.resolver.resolveComponentFactory(PdfHtmlComponent);

    const componentRef = this.container.createComponent(factory);
    componentRef.instance.title = 'Injected Title';

    asyncScheduler.schedule(() => {
      const htmlString = componentRef.location.nativeElement.innerHTML;
      componentRef.destroy();
      console.log('HTML STRING:', htmlString);
    });
  }
}

app.component.html

<button (click)="getPDFHtml()">CLICK TO GET COMPONENT HTML</button>
<p>Output is in the console</p>
<div [hidden]="true">
  <template #pdfHtml></template>
</div>

pdf-html.component.ts

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

@Component({
  selector: 'pdf-html',
  templateUrl: './pdf-html.component.html',
})
export class PdfHtmlComponent {
  title: string = 'Default Title';

  STYLES: any = {
    MAIN_CONTAINER: 'background:red;',
    ITEM_BOX: 'color:red;',
  };
}

pdf-html.component.html

<h2>Title: {{ title }}</h2>

<table style="{{ STYLES.MAIN_CONTAINER }}">
  <tr style="{{ STYLES.ITEM_BOX }}">
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr style="{{ STYLES.ITEM_BOX }}">
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr style="{{ STYLES.ITEM_BOX }}">
    <td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr>
  <tr style="{{ STYLES.ITEM_BOX }}">
    <td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr>
</table>

Демонстрацию можно посмотреть здесь

или вы можете поиграть с кодом здесь

Удачного кодирования!!! 🎉🎉🎉


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE