Можно ли использовать ng-content в корневом компоненте приложения?

У меня есть рабочее приложение angular. Я хочу интегрировать его с системой управления контентом, которая создает статические страницы, но для этого мне нужно использовать проекцию контента изindex.html страница.

Что-то вроде этого:

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>AngularBacktest</title>
        <base href="/">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="icon" type="image/x-icon" href="favicon.ico">
      </head>
      <body>
        <app-root>Text injected from index.html</app-root>
      </body>
    </html>

Затем app-root компонент реализует проекцию контента, включая <ng-content></ng-content> в своем шаблоне:

  @Component({
    selector: 'app-root',
    template: '<p>Content projection from outside:11<ng-content></ng-content>11</p>',
    styleUrls: ['./app.component.css']
  })
  export class AppComponent { }

Увы, похоже, что все работает не так, как хотелось бы. После компиляции и запуска приложения результат рендеринга будет следующим:

  • Проекция контента извне:1111

Это мой вопрос:

  • Можно ли использовать проекцию контента извне приложения angular, как в примере выше?
  • Если да, то как? Если нет, то почему?

Изменить: в некоторых комментариях меня спрашивают, зачем мне что-то подобное. Итак, вот почему: мое приложение Angular предоставляет настраиваемые компоненты, реализующие моделирование финансового бэк-тестирования. Это включает в себя выборку исторических котировок, запуск моделирования и отображение результатов на графике. Я хотел бы отобразить симуляции, работающие в такой среде, как WordPress, Dokuwiki или даже статические страницы, обслуживаемые каким-либо экземпляром Apache. Это может быть пример:

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>Pure Buy &amp; Hold example</title>
        <base href="./">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="icon" type="image/x-icon" href="favicon.ico">
      </head>
      <body>
        <p>This simulation shows a pure <em>Buy &amp; Hold</em>, investing
        100'001USD in the S&amp;P500, between 2000, January the 1st, and    
        2020 January the 1st:</p>
        <app-root>
          <simulation start="2000-01-01" end="2020-4-9" quotes="SPY">
              <chart-report>
                  <chart-report-configuration show="SPY.CLOSE" showDataAs="LINE" showDataOn="LEFT"    normalize="true"    ></chart-report-configuration>
                  <chart-report-configuration show="BAH.NAV"     showDataAs="LINE" showDataOn="LEFT"    normalize="true"    ></chart-report-configuration>
              </chart-report>
              <accounts>
                  <swiss-quote id="BAH" cash="100000">
                      <strategy>
                          <buy-and-hold assetName="SPY"></buy-and-hold>
                      </strategy>
                  </swiss-quote>
              </accounts>
          </simulation>
        </app-root>
        <p/>Blah blah blah blah</p>
      </body>
    </html>

1 ответ

В настоящее время, начиная с Angular до версии 15, невозможно внедрить корневой контент приложения с помощью ng-content, но эта функция находится на рассмотрении. Для этого существует открытая проблема с более подробной информацией: https://github.com/angular/angular/issues/4946 .


Мое решение показать индикатор начальной загрузки состоит в том, чтобы изначально разместить содержимое корня приложения по умолчанию вне корня приложения, а затем проецировать его в компонент приложения.

index.html

      ...
<body>
  <div id="initialization-container">
    Initializing...
  </div>
  <app-root></app-root>
</body>
...

app.comComponent.html

      <ng-container *ngIf="isInitializing$ | async; else appInitialized">
  <app-initialization-container/>
</ng-container>

<ng-template #appInitialized>
  APPLICATION
</ng-template>

инициализация-container.ts

      import {AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Renderer2} from '@angular/core';

@Component({
  selector: 'app-initialization-container',
  template: '',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class InitializationContainerComponent implements AfterViewInit {
  constructor(
    private render: Renderer2,
    private hostRef: ElementRef
  ) {
  }

  ngAfterViewInit() {
    const el = document.getElementById('initialization-container');
    if (el != null) {
      this.render.appendChild(this.hostRef.nativeElement, el);
    }
  }
}

Другой вариант использования индикатора загрузки — просто удалить его из DOM после завершения загрузки, но этот пример также должен продемонстрировать, как проецировать контент в приложение в соответствии с вашим вариантом использования.

Другие вопросы по тегам