Можно ли использовать 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 & 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 & Hold</em>, investing
100'001USD in the S&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 после завершения загрузки, но этот пример также должен продемонстрировать, как проецировать контент в приложение в соответствии с вашим вариантом использования.