Angular 多个 ng-content 组件不生效

我试图建立一个自定义组件使用多个 ng-content在 Angular 6,但这是不工作,我不知道为什么。

这是我的组件代码:

我试图在另一个地方使用这个组件,并在 bodyng-content的头 select中呈现两个不同的 HTML 代码,类似于这样:

This should be rendered in header selection of ng-content
This should be rendered in body selection of ng-content

但组件呈现的是空白。

你们知道我可能做错了什么吗? 或者在同一个组件中渲染两个不同部分的最佳方法是什么?

谢谢!

136580 次浏览
  1. 您可以添加虚拟属性 headerbody,而不是模板引用 (#header, #body)
  2. 使用具有 select属性的 ng-content,如 select="[header]"

App.comp.html

<app-child>
<div header >This should be rendered in header selection of ng-content</div>
<div body >This should be rendered in body selection of ng-content</div>
</app-child>

儿童网站

<div class="header-css-class">
<ng-content select="[header]"></ng-content>
</div>
<div class="body-css-class">
<ng-content select="[body]"></ng-content>
</div>

演示

你亦可使用:

App.comp.html

<app-child>
<div role="header">This should be rendered in header selection of ng-content</div>
<div role="body">This should be rendered in body selection of ng-content</div>
</app-child>

儿童网站

<div class="header-css-class">
<ng-content select="div[role=header]"></ng-content>
</div>
<div class="body-css-class">
<ng-content select="div[role=body]"></ng-content>
</div>

符合 Web 组件规格。即使那是角度。这是关于避免选择器的属性,如角度指令或保留属性与其他用途。因此,我们只使用“槽”属性。我们将看到 <ng-content select="[slot=foobar]"><slot name="foobar">

例如:

Hello-world. Component.html

<ng-content select="[slot=start]"></ng-content>
<span>Hello World</span>
<ng-content select="[slot=end]"></ng-content>

App.Component. html

<app-hello-world>
<span slot="start">This is a </span>
<span slot="end"> demo.</span>
</app-hello-world>

结果

This is a Hello World demo.

Stackblitz 示例

你可以用任何你想用的名字,比如“香蕉”或者“鱼”。但是“开始”和“结束”是在元素之前和之后放置元素的一个很好的约定。

补充其他答案:

您也可以使用自定义标记(如 <ion-card><ion-card-header><ion-card-content>)进行此操作。

App.comp.html

<app-child>
<app-child-header>This should be rendered in header selection of ng-content</app-child-header>
<app-child-content>This should be rendered in content selection of ng-content</app-child-content>
</app-child>

儿童网站

<div class="header-css-class">
<ng-content select="app-child-header"></ng-content>
</div>
<div class="content-css-class">
<ng-content select="app-child-content"></ng-content>
</div>

你会得到一个警告信息,但它会工作。 可以禁止显示警告消息或 使用已知标签,如 headerfooter。 但是,如果您不喜欢这些方法中的任何一种,您应该使用其他解决方案中的一种。

作为另一个选项,您可以将模板传递给子组件,然后您可以将值绑定到内容/模板

父组件 html

<app-child
[templateHeader]="header"
[templateContent]="content">
</app-child>


<ng-template #header
let-data="data"> < -- how you get dynamic data
what ever you would like the header to say
\{\{data}}
</ng-template>


<ng-template #content>
what ever you would like the content to say or any other component
</ng-template>

子组件 t

export class ChildComponent {
@Input() templateHeader: TemplateRef<any>;
@Input() templateContent: TemplateRef<any>;
}

子组件 html

<div class="header-css-class">
<ng-container
*ngTemplateOutlet="
templateHeader;
context: {   , < -- if you want to pass data to your template
data: data
}">
</ng-container>
</div>
<div class="content-css-class">
<ng-container *ngTemplateOutlet="templateContent">
</ng-container>
</div>

有关模板的更完整的解释,请参阅这篇伟大的文章 https://indepth.dev/posts/1405/ngtemplateoutlet

如果您只想“接受”多个组件,可以使用:

<ng-content select="custom-component,a"></ng-content>

它接受自定义组件的元素以及锚(a)元素,并且不改变序列。