詳細ガイド
コンポーネント

ng-content を使ったコンテンツの投影

Tip: このガイドは、すでに 基本概念のガイド を読んだことを前提としています。Angularを初めて使う場合は、まずそちらを読んでください。

多くの場合、さまざまな種類のコンテンツを格納するコンポーネントを作成する必要があります。 例えば、カスタムカードコンポーネントを作成したいとします。

      
@Component({  selector: 'custom-card',  template: '<div class="card-shadow"> <!-- card content goes here --> </div>',})export class CustomCard {/* ... */}

<ng-content>要素は、コンテンツを配置する場所を示すプレースホルダーとして使用できます。:

      
@Component({  selector: 'custom-card',  template: '<div class="card-shadow"> <ng-content></ng-content> </div>',})export class CustomCard {/* ... */}

Tip: <ng-content>は、 ネイティブの<slot>要素と似ていますが、 Angular固有の機能も備えています。

<ng-content>を使用したコンポーネントを使用する場合、 コンポーネントホスト要素の子要素はすべて、その<ng-content>の場所にレンダリング、あるいは投影されます:

      
// コンポーネントソース@Component({  selector: 'custom-card',  template: `    <div class="card-shadow">      <ng-content />    </div>  `,})export class CustomCard {/* ... */}
      
<!-- コンポーネントの利用 --><custom-card>  <p>これは投影されたコンテンツです</p></custom-card>
      
<!-- レンダリングされたDOM --><custom-card>  <div class="card-shadow">    <p>これは投影されたコンテンツです</p>  </div></custom-card>

Angularは、このように渡されるコンポーネントの子要素を、そのコンポーネントのコンテンツと呼びます。 これはコンポーネントのビューとは異なります。 ビューは、コンポーネントのテンプレートで定義された要素を指します。

<ng-content>要素は、コンポーネントでもDOM要素でもありません。 代わりに、コンテンツをレンダリングする場所をAngularに伝える特別なプレースホルダーです。 Angularのコンパイラは、ビルド時にすべての<ng-content>要素を処理します。 実行時に<ng-content>の挿入や削除、変更はできません。ディレクティブやスタイル、任意の属性も<ng-content>には追加できません。

<ng-content>@if@for、または@switchによって条件付きで含めるべきではありません。 Angularは常にレンダリングされたコンテンツのDOMノードをインスタンス化して作成します。 その<ng-content>プレースホルダが非表示であってもです。コンポーネントコンテンツの条件付きレンダリングについては テンプレートフラグメントを参照してください。

複数のコンテンツプレースホルダー

Angularは、CSSセレクターに基づいて、複数の異なる要素を異なる<ng-content>プレースホルダーへの投影をサポートしています。 上記のカードの例を拡張して、select属性を使用して、 カードのタイトルと本文の2つのプレースホルダーを作成できます。

      
<!-- コンポーネントテンプレート --><div class="card-shadow">  <ng-content select="card-title"></ng-content>  <div class="card-divider"></div>  <ng-content select="card-body"></ng-content></div>
      
<!-- コンポーネントの利用 --><custom-card>  <card-title>こんにちは</card-title>  <card-body>例へようこそ</card-body></custom-card>
      
<!-- レンダリングされたDOM --><custom-card>  <div class="card-shadow">    <card-title>こんにちは</card-title>    <div class="card-divider"></div>    <card-body>例へようこそ</card-body>  </div></custom-card>

<ng-content>プレースホルダーは、 コンポーネントセレクターと同じCSSセレクターをサポートしています。

select属性を持つ<ng-content>プレースホルダーを1つ以上、 select属性を持たない<ng-content>プレースホルダーを1つ含める場合、 後者はselect属性に一致しなかったすべての要素をキャプチャします。

      
<!-- コンポーネントテンプレート --><div class="card-shadow">  <ng-content select="card-title"></ng-content>  <div class="card-divider"></div>  <!-- "card-title"以外をすべてキャプチャ -->  <ng-content></ng-content></div>
      
<!-- コンポーネントの利用 --><custom-card>  <card-title>こんにちは</card-title>  <img src="..." />  <p>例へようこそ</p></custom-card>
      
<!-- レンダリングされたDOM --><custom-card>  <div class="card-shadow">    <card-title>こんにちは</card-title>    <div class="card-divider"></div>    <img src="..." />    <p>例へようこそ></p>  </div></custom-card>

コンポーネントにselect属性を持たない<ng-content>プレースホルダーが含まれていない場合、 コンポーネントのいずれかのプレースホルダーに一致しない要素はDOMにレンダリングされません。

フォールバックコンテンツ

Angularは、コンポーネントの<ng-content>プレースホルダーに一致する子コンテンツがない場合、コンポーネントの<ng-content>プレースホルダーにフォールバックコンテンツを表示できます。<ng-content>要素自体に子コンテンツを追加することで、フォールバックコンテンツを指定できます。

      
<!-- コンポーネントテンプレート --><div class="card-shadow">  <ng-content select="card-title">Default Title</ng-content>  <div class="card-divider"></div>  <ng-content select="card-body">Default Body</ng-content></div>
      
<!-- コンポーネントの利用 --><custom-card>  <card-title>Hello</card-title>  <!-- No card-body provided --></custom-card>
      
<!-- レンダリングされたDOM --><custom-card>  <div class="card-shadow">    Hello    <div class="card-divider"></div>    Default Body  </div></custom-card>

投影のためのコンテンツのエイリアシング

Angularは、任意の要素にCSSセレクターを指定できる特殊な属性ngProjectAsをサポートしています。 ngProjectAsを持つ要素が<ng-content>プレースホルダーに対してチェックされると、 Angularは要素のIDではなくngProjectAsの値と比較します。

      
<!-- コンポーネントテンプレート --><div class="card-shadow">  <ng-content select="card-title"></ng-content>  <div class="card-divider"></div>  <ng-content></ng-content></div>
      
<!-- コンポーネントの利用 --><custom-card>  <h3 ngProjectAs="card-title">こんにちは</h3>  <p>例へようこそ</p></custom-card>
      
<!-- レンダリングされたDOM --><custom-card>  <div class="card-shadow">    <h3>こんにちは</h3>    <div class="card-divider"></div>    <p>例へようこそ></p>  </div></custom-card>

ngProjectAsは静的な値のみをサポートし、動的な式にはバインドできません。