将ng模板的ng内容从一个组件获取到另一个组件中



我知道还有其他想法,但我想以下面定义的方式使用ng-templateng-content@ContenChild()装饰器。这种想法是通过观察有角度的材料组件的实际实现而产生的。

这里,我有两个组件:

  1. 容器组件(应用程序容器(
  2. 子组件(应用程序子组件(

我想直接在应用容器中显示应用子组件的内容。

我在这里得到了一些相关的解决方案: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);
}
}

Stacklitz演示

我认为不使用ngTemplateOutlet会得到一个更干净的结构。IMO,您甚至不需要任何ng-template元素。当然,我不知道你的最终目标,但你可以做我下面展示的,这与你的非常相似,但我认为app-container中的可选ng-content使整体结构更直观,更容易理解组件的树设置:

@Component({
selector: "app-main",
template: `<ng-content></ng-content>`
})
export class AppMain {}
@Component({
selector: "app-nav",
template: `<ng-content></ng-content>`
})
export class AppNav {}
@Component({
selector: "app-container",
template: `
<div class="container">
<nav role="navigation" class="navigation">
<ng-content select="[nav-slot]"></ng-content>
</nav>
<section role="main" class="main__content">
<ng-content select="[main-slot]"></ng-content>
</section>
</div>
`
})
export class AppContainer {
@ContentChild(AppMain) main: AppMain;
@ContentChild(AppNav) nav: AppNav;
ngAfterContentInit() { /* ... */}
}

你可以这样使用它:

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

我得到了解决方案!!

实际上,为了获得任何组件的内容,我们可以使用@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>

相关内容

  • 没有找到相关文章

最新更新