多种ng含量


103

我正在尝试使用ng-contentAngular 6中的多个组件来构建自定义组件,但这不起作用,我也不知道为什么。

这是我的组件代码:

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

我试图在另一个地方使用此组件,并在body和的标头select中呈现两个不同的HTML代码ng-content,如下所示:

<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>

但是组件使空白。

你们知道我可能做错了什么,还是在同一组件中呈现两个不同部分的最佳方法是什么?

谢谢!


抱歉,stackoverflow没有保存我的第二个代码片段:我在组件中使用的代码是这样的:<div #header>这是标题内容</ div> <div #body>这是正文内容</ div>
卢卡斯·桑托斯

Answers:


194
  1. 您可以添加虚拟属性headerbody而不是模板引用(#header, #body)
  2. 并排除使用ng-contentwith等select属性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>

child.comp.html

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

演示


7
如果您不想渲染其他div或任何其他标签,则应使用<ng-container>
sobczi

3
@AmitChigadani我相信@sobczi表示您可以替换<div header><ng-container header>
user12893298320392 '20

4
我确定更换<div header><ng-container header>作品了。
azerafati

51

符合Web组件规格。即使那是Angular。这是关于避免将诸如Angular指令之类的选择器属性或保留属性用于其他用途。因此,我们只使用“插槽”属性。我们将看到<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"> example.</span>
</app-hello-world>

结果

This is a Hello World example.

Stackblitz示例

您可以使用任何想要的名称,例如“香蕉”或“鱼”。但是“开始”和“结束”是在元素之前和之后放置元素的好习惯。


如何查询这些元素?与名称槽。
Nexeuz

这取决于您的角度和组件设置以及您真正想要的是什么。您可以在TS或:host::ng-deepSCSS中使用ViewChild 。但这只是一个例子。参见Stackblitz也许::slotted/::content也可以。但不确定。网络将提供有关此主题的更多信息。通常,您只应设置组件本身的样式。并避免在外部(全局)设置样式。否则会有不良的副作用。
多米尼克

好的做法是将其包装。请参阅我最近的评论中更新的Stackblitz示例。请参阅组件的html和css文件。您应该更喜欢ng-deep。例如,<div class="end"><ng-content></ng-content></div>因为此元素在组件中可访问。ng-content只是一个伪元素,由外部的停靠元素代替。因此,您必须使用ng-deep选择器。
多米尼克

9

或者,您可以使用:

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>

child.comp.html

<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>

4

补充其他答案:

您还可以使用自定义标签做到这一点(如<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>

child.comp.html

<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>

您会收到一条警告消息,但它会起作用。您可以禁止显示警告消息或使用诸如header或的已知标签footer。但是,如果您不喜欢这些方法中的任何一种,则应选择其他解决方案之一。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.