複数の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>

このコンポーネントを別の場所で使用して、次のような2つの異なるHTMLコードを内部bodyとヘッダーselectにレンダリングしようとしています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>

しかし、コンポーネントは空白になっています。

私が間違っている可能性があること、または同じコンポーネントで2つの異なるセクションをレンダリングするための最良の方法を知っていますか?

ありがとう!


申し訳ありませんが、stackoverflowは2番目のコードスニペットを保存しませんでした:コンポーネントで使用しているコードは次のようなものです:<div#header>これはヘッダーコンテンツです</ div> <div#body>これはボディコンテンツです</ div>
ルーカスサントス

回答:


193
  1. テンプレート参照ではなく、ダミー属性headerを追加できbodyます(#header, #body)
  2. そして、のような属性でを使用ng-contentしてトランスクルージョンし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-コンテナ>を使用する必要があります
sobczi

3
@AmitChigadani @sobcziは、に置き換えることができること<div header>を意味すると思います<ng-container header>
user128932983203 9220

4
作品への交換も確認<div header>して<ng-container header>おります。
azerafati

51

Webコンポーネントの仕様に合わせるため。たとえそれがAngularだとしても。これは、Angularディレクティブや予約済み属性などのセレクターの属性を別の用途で回避することです。したがって、「slot」属性を使用するだけです。<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

それはあなたのAngularとコンポーネントの設定とあなたが正確に何を望んでいるかに依存します。あなたは、TSやViewChildを使用することができます:hostし、::ng-deepSCSSで。しかし、これは単なる例です。Stackblitzを参照してください多分::slotted/::contentも動作します。しかし、確かではありません。Webは、このトピックに関する詳細を提供します。通常は、コンポーネント自体のスタイルのみを設定する必要があります。また、外部(グローバル)でのスタイリングは避けてください。そうしないと、望ましくない副作用が発生します。
ドミニク

ラップすることをお勧めします。私の最後のコメントで更新された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ます。ただし、これらの方法のいずれかが気に入らない場合は、他の解決策のいずれかを使用する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.