詳細ガイド
テンプレート

<ng-template> を使用したテンプレートフラグメントの作成

ネイティブの <template> 要素 に触発されて、<ng-template> 要素を使用すると、テンプレートフラグメント、つまり動的またはプログラムによってレンダリングできるコンテンツのセクションを宣言できます。

テンプレートフラグメントの作成

<ng-template> 要素を使用して、コンポーネントテンプレート内のどこにでもテンプレートフラグメントを作成できます。

      
<p>これは通常の要素です</p><ng-template>  <p>これはテンプレートフラグメントです</p></ng-template>

上記のコードをレンダリングすると、<ng-template> 要素の内容はページにレンダリングされません。代わりに、テンプレートフラグメントへの参照を取得して、コードを記述して動的にレンダリングできます。

フラグメントのコンテキストの結合

テンプレートフラグメントには、動的な式を含む結合を含めることができます。

      
@Component({  /* ... */,  template: `<ng-template>選択した項目は {{count}} 個です。</ng-template>`,})export class ItemCounter {  count: number = 0;}

テンプレートフラグメント内の式またはステートメントは、フラグメントがレンダリングされる場所とは関係なく、フラグメントが宣言されているコンポーネントに対して評価されます。

テンプレートフラグメントへの参照の取得

テンプレートフラグメントへの参照は、次のいずれかの方法で取得できます。

これらのすべての場合において、フラグメントは TemplateRef オブジェクトによって表されます。

テンプレート参照変数を使用したテンプレートフラグメントへの参照

テンプレート参照変数を <ng-template> 要素に追加することで、同じテンプレートファイル内の他の部分でそのテンプレートフラグメントを参照できます。

      
<p>これは通常の要素です</p><ng-template #myFragment>  <p>これはテンプレートフラグメントです</p></ng-template>

その後、myFragment 変数を使用して、テンプレート内の他の場所でこのフラグメントを参照できます。

クエリを使用したテンプレートフラグメントへの参照

コンポーネントまたはディレクティブクエリAPI を使用して、テンプレートフラグメントへの参照を取得できます。

たとえば、テンプレートにテンプレートフラグメントが1つだけ含まれている場合は、@ViewChild クエリを使用して TemplateRef オブジェクトを直接クエリできます。

      
@Component({  /* ... */,  template: `    <p>これは通常の要素です</p>    <ng-template>      <p>これはテンプレートフラグメントです</p>    </ng-template>  `,})export class ComponentWithFragment {  @ViewChild(TemplateRef) myFragment: TemplateRef<unknown> | undefined;}

その後、他のクラスメンバーと同様に、コンポーネントコードまたはコンポーネントのテンプレート内でこのフラグメントを参照できます。

テンプレートに複数のフラグメントが含まれている場合は、各 <ng-template> 要素にテンプレート参照変数を追加して、その名前でフラグメントをクエリすることで、各フラグメントに名前を付けることができます。

      
@Component({  /* ... */,  template: `    <p>これは通常の要素です</p>    <ng-template #fragmentOne>      <p>これはテンプレートフラグメントの 1 つです</p>    </ng-template>    <ng-template #fragmentTwo>      <p>これは別のテンプレートフラグメントです</p>    </ng-template>  `,})export class ComponentWithFragment {  // 名前でクエリを行う場合、`read` オプションを使用して、  // 要素に関連付けられている `TemplateRef` オブジェクトを取得したいことを指定できます。  @ViewChild('fragmentOne', {read: TemplateRef}) fragmentOne: TemplateRef<unknown> | undefined;  @ViewChild('fragmentTwo', {read: TemplateRef}) fragmentTwo: TemplateRef<unknown> | undefined;}

繰り返しますが、他のクラスメンバーと同様に、コンポーネントコードまたはコンポーネントのテンプレート内でこれらのフラグメントを参照できます。

テンプレートフラグメントの注入

ディレクティブは、そのディレクティブが <ng-template> 要素に直接適用されている場合、TemplateRef を注入できます。

      
@Directive({  selector: '[myDirective]'})export class MyDirective {  private fragment = inject(TemplateRef);}
      
<ng-template myDirective>  <p>これはテンプレートフラグメントの 1 つです</p></ng-template>

その後、他のクラスメンバーと同様に、ディレクティブコード内でこのフラグメントを参照できます。

テンプレートフラグメントのレンダリング

TemplateRef オブジェクトへの参照を取得したら、NgTemplateOutlet ディレクティブを使用してテンプレート内でフラグメントをレンダリングするか、ViewContainerRef を使用してTypeScriptコード内でフラグメントをレンダリングできます。

NgTemplateOutlet の使用

@angular/commonNgTemplateOutlet ディレクティブは、TemplateRef を受け取り、アウトレットに要素を持つ要素の兄弟としてフラグメントをレンダリングします。通常、NgTemplateOutlet<ng-container> 要素 で使用する必要があります。

まず、NgTemplateOutlet をインポートします:

      
import { NgTemplateOutlet } from '@angular/common';

次の例では、テンプレートフラグメントを宣言し、そのフラグメントを NgTemplateOutlet を使用して <ng-container> 要素にレンダリングします。

      
<p>これは通常の要素です</p><ng-template #myFragment>  <p>これはフラグメントです</p></ng-template><ng-container *ngTemplateOutlet="myFragment"></ng-container>

この例では、次のレンダリングされたDOMが生成されます。

      
<p>これは通常の要素です</p><p>これはフラグメントです</p>

ViewContainerRef の使用

ビューコンテナは、Angularのコンポーネントツリー内の、コンテンツを含めることができるノードです。コンポーネントまたはディレクティブはすべて、ViewContainerRef を注入して、そのコンポーネントまたはディレクティブのDOM内の位置に対応するビューコンテナへの参照を取得できます。

ViewContainerRefcreateEmbeddedView メソッドを使用して、テンプレートフラグメントを動的にレンダリングできます。ViewContainerRef を使用してフラグメントをレンダリングすると、Angularは、ViewContainerRef を注入したコンポーネントまたはディレクティブの次の兄弟として、そのフラグメントをDOMに追加します。

次の例は、テンプレートフラグメントへの参照を入力として受け取り、ボタンクリック時にそのフラグメントをDOMにレンダリングするコンポーネントを示しています。

      
@Component({  /* ... */,  selector: 'component-with-fragment',  template: `    <h2>フラグメントを含むコンポーネント</h2>    <ng-template #myFragment>      <p>これがフラグメントです</p>    </ng-template>    <my-outlet [fragment]="myFragment" />  `,})export class ComponentWithFragment { }@Component({  /* ... */,  selector: 'my-outlet',  template: `<button (click)="showFragment()">表示</button>`,})export class MyOutlet {  private viewContainer = inject(ViewContainerRef);  @Input() fragment: TemplateRef<unknown> | undefined;  showFragment() {    if (this.fragment) {      this.viewContainer.createEmbeddedView(this.fragment);    }  }}

上記の例では、「表示」ボタンをクリックすると、次の出力が生成されます。

      
<component-with-fragment>  <h2>フラグメントを含むコンポーネント>  <my-outlet>    <button>表示</button>  </my-outlet>  <p>これがフラグメントです</p></component-with-fragment>

テンプレートフラグメントのレンダリング時のパラメータの受け渡し

<ng-template> を使用してテンプレートフラグメントを宣言する際、さらにフラグメントで受け入れられるパラメータを宣言できます。フラグメントをレンダリングする際には、これらのパラメータに対応する context オブジェクトを最適に渡すことができます。このコンテキストオブジェクトのデータは、結合式やステートメント内で使用できます。また、フラグメントが宣言されているコンポーネントからのデータも参照できます。

各パラメータは、let- プレフィックスを付けた属性として記述され、値はコンテキストオブジェクトのプロパティ名と一致しています。

      
<ng-template let-pizzaTopping="topping">  <p>選択したのは: {{pizzaTopping}}</p></ng-template>

NgTemplateOutlet の使用

ngTemplateOutletContext 入力にコンテキストオブジェクトを結合できます。

      
<ng-template #myFragment let-pizzaTopping="topping">  <p>選択したのは: {{pizzaTopping}}</p></ng-template><ng-container  [ngTemplateOutlet]="myFragment"  [ngTemplateOutletContext]="{topping: '玉ねぎ'}"/>

ViewContainerRef の使用

createEmbeddedView に対する2番目の引数として、コンテキストオブジェクトを渡すことができます。

      
this.viewContainer.createEmbeddedView(this.myFragment, {topping: '玉ねぎ'});

構造ディレクティブ

構造ディレクティブとは、次のいずれかの条件を満たすディレクティブです。

  • TemplateRef を注入する
  • ViewContainerRef を注入し、注入された TemplateRef をプログラムによってレンダリングする

Angularは、構造ディレクティブ向けの特別な便利な構文をサポートしています。ディレクティブを要素に適用し、ディレクティブのセレクターの前にアスタリスク (*) 文字を付けると、Angularは要素全体とそのコンテンツ全体をテンプレートフラグメントとして解釈します。

      
<section *myDirective>  <p>これがフラグメントです</p></section>

これは、次のコードと同じです。

      
<ng-template myDirective>  <section>    <p>これがフラグメントです</p>  </section></ng-template>

開発者は通常、構造ディレクティブを使用して、フラグメントを条件付きでレンダリングしたり、フラグメントを複数回レンダリングしたりします。

詳細については、構造ディレクティブ を参照してください。

さらなるリソース

ng-template が他のライブラリで使用される方法の例については、以下を確認してください。