typescript 是否可以在app-root组件中使用ng-content?

omjgkv6w  于 2023-05-08  发布在  TypeScript
关注(0)|答案(1)|浏览(102)

我有一个工作的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>
laik7k3q

laik7k3q1#

目前,在Angular v15版本中,这是不可能的,因为ng-content不能注入app-root内容,但这是一个正在考虑的功能。有一个开放的问题,有更多的细节:https://github.com/angular/angular/issues/4946
我显示初始加载指示器的解决方案是让默认的app-root内容最初位于app-root之外,然后将其投影到app-component中。
index.html

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

app.component.html

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

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

initialization-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中删除,但此示例还应演示如何将内容投影到应用程序中以适应您的用例。

相关问题