首页 > 解决方案 > 从一个组件中获取 ng-template 的 ng-content 到另一个组件中

问题描述

我知道还有其他想法,但我想以下面定义的方式使用ng-template,ng-content@ContenChild()装饰器。这种想法来自于看到角材料组件的实际实现。

在这里,我有两个组件:

  1. 容器组件(app-container)
  2. 子组件(app-child)

我想在 app-container 中直接显示 app-child 组件的内容。

我在这里有一些相关的解决方案:https ://stackblitz.com/edit/ngtemplateoutlet-and-content-projection?file=src%2Fapp%2Fapp.component.html 。但这并不能完全满足我的要求。

需要以下 html,主要在app.component.html

<app-container>
   <app-nav>
       <a routerLink="/home">Home</a>
       <a routerLink="/about">About</a>
   </app-nav>
  <app-main>
    <p>This is the content to be reflect.</p>
  </app-main>
</app-container>

应该产生这样的输出:

<div class="container">
        <nav role="navigation" class="navigation">
             <a routerLink="/home">Home</a>
             <a routerLink="/about">About</a>
        </nav>
        <section role="main" class="main__content">
               <p>This is the content to be reflect.</p>
        </section>
</div>

我的代码看起来像这样

import { Component, ContentChild, AfterContentInit } from '@angular/core';

@Component({
    selector: 'app-main'
    template: `<ng-template><ng-content></ng-content></ng-template>`
})
export class AppMain {

}
@Component({
    selector: 'app-nav'
    template: `<ng-template><ng-content></ng-content></ng-template>`
})
export class AppNav {

}


@Component({
    selector: 'app-container',
    template: `
               <div class="container">
                      <nav role="navigation" class="navigation">
                         <ng-container [ngTemplateOutlet="nav"></ng-container>
                      </nav>
                      <section role="main" class="main__content">
                         <ng-container [ngTemplateOutlet]="main"></ng-container>
                      </section>
               </div>
              `
})
export class AppContainer implements AfterContentInit {
    @ContentChild(AppMain) main: AppMain;
    @ContentChild(AppNav) nav: AppNav;

    ngAfterContentInit() {       
        console.log(this.main);
        console.log(this.nav);
    }
}


标签: angularng-templateng-content

解决方案


我得到了解决方案!

实际上,要获取任何组件的内容,我们可以使用@ViewChild()装饰器。因此,对于app-navapp-main组件,我使用了相同的技术,如下所示:

import { Component, ContentChild, AfterContentInit, TemplateRef, ViewChild } from '@angular/core';
@Component({
    selector: 'app-main',
    template: `<ng-template><ng-content></ng-content></ng-template>`
})
export class AppMain{
    @ViewChild(TemplateRef, { static: true }) content: TemplateRef<any>;
}
@Component({
    selector: 'app-nav',
    template: `<ng-template><ng-content></ng-content></ng-template>`
})
export class AppNar {
    @ViewChild(TemplateRef, { static: true }) content: TemplateRef<any>;

}


@Component({
    selector: 'app-container',
    template: `
               <div class="container">
                      <nav role="navigation" class="navigation">
                         <ng-container [ngTemplateOutlet="nav.content"></ng-container>
                      </nav>
                      <section role="main" class="main__content">
                         <ng-container [ngTemplateOutlet]="main.content"></ng-container>
                      </section>
               </div>
              `
})
export class AppContainer implements AfterContentInit {

    @ContentChild(AppMain) main: AppMain;
    @ContentChild(AppNav) nav!: AppNav;

    ngAfterContentInit() {

    }

}

所以,在 中app.component.html,我有:

<app-container>
   <app-nav>
       <a routerLink="/home">Home</a>
       <a routerLink="/about">About</a>
   </app-nav>
  <app-main>
    <p>This is the content to be reflect.</p>
  </app-main>
</app-container>

我得到的输出实际上是想要的输出:

<div class="container">
        <nav role="navigation" class="navigation">
             <a routerLink="/home">Home</a>
             <a routerLink="/about">About</a>
        </nav>
        <section role="main" class="main__content">
               <p>This is the content to be reflect.</p>
        </section>
</div>

推荐阅读