[Angular] (Tips)テンプレート内でng-templateを使い回す


Angularのng-template のHowToメモ

よくあるベタなケース

<!-- ......略 -->
<!--コンポーネント側で変数 "hoge"があるとする -->
<ng-container *ngIf="hoge; else elseTemplate">
  hoge is true  :)
</ng-container>

<ng-template #elseTemplate>
hoge is false !
</ng-template>

と書くと、hoge = falseのときはng-templateで定義したelseTemplateが表示される。
(ベタ。でも*ngIf="!hoge"と書くのとそこまで変わらないからあんまりありがたくない。*ngIfの条件が長いときはあり。)

知っておくと便利かもしれないやつ①

<!-- ......略 -->
<!-- 同じテンプレートファイル内で単純にhtmlを使いまわしたい場合 -->

<ng-template #kurikaesi>
<dl>
  <dt>name</dt>
  <dd>hoge</dd>
</dl>
<ng-template>

<!-- これでつかいまわせる -->
<ng-container *ngTemplateOutlet="kurikaesi"></ng-container>
<ng-container *ngTemplateOutlet="kurikaesi"></ng-container>
<ng-container *ngTemplateOutlet="kurikaesi"></ng-container>

マイナーかもしれない。

知っておくと便利かもしれないやつ②

<!-- ......略 -->
<!-- 同じテンプレートファイル内でhtmlを使いまわしたい場合でng-template内で変数を使いたいとき -->
<!--
コンポネント側で hoge = { name:string , age:number} が定義されている場合
-->

<ng-template #kurikaesi let-hoge>
<dl>
  <dt>{{hoge.name}}</dt>
  <dd>{{hoge.age}}</dd>
</dl>
<ng-template>

<!-- これでつかいまわせる -->
<ng-container *ngTemplateOutlet="kurikaesi; context:{$implicit:hoge}"></ng-container>

ngForでループさせるときに、ngForのletで定義したテンプレート上の変数を context:{$implicit:hoge}のhoge部分に渡したりすると、(コンポーネント(.ts)を汚さなくて手軽に使いまわしが効いて)結構便利。
けっこうマイナーな使い方かもしれない。

コンポーネント間のテンプレートの受け渡し(ng-Templateでやる場合)

hoge-component.ts
/**
*  @ContentChildでTemplateを渡せるようにしておく
*/

@Component({
  selector: 'hoge',
  templateUrl: '....', // 略
  styleUrls: ['....'],// 略
})

export class SsPopoverComponent{
  @ContentChild(TemplateRef) bodyTemplate: TemplateRef<any>;
}

hoge-component.html
<!-- ......略 -->
<ng-container *ngTemplateOutlet="bodyTemplate"></ng-container>
<!-- ......略 -->
parent-component.html
<!-- 親のコンポーネントからhogeコンポーネントへテンプレートを渡す -->
<!-- もちろん、親コンポネント内で`.hoge-content`へスタイルを当てられる -->
<hoge>
  <ng-template>
  <span class="hoge-content">
    hogehoge
  </span>
  </template>
</hoge>

おそらく今回の受け取ったテンプレートをただ表示するだけのようなユースケースではng-content を使ったほうがいいが、子(今回はhoge)コンポーネント内で、親からテンプレートを渡されるかどうかで表示を切り分ける場合はng-templateを渡したほうがきれいに書ける(気がする)。

hoge-component.html
<!-- 親からテンプレートを渡されるかどうかで表示を切り分ける場合 -->

<!-- ......略 -->
<ng-template #defaultTemplate>
  is Empty!
</ng-template>

<ng-container *ngTemplateOutlet="bodyTemplate? bodyTemplate : defaultTemplate"></ng-container>
<!-- ......略 -->

参考
https://alligator.io/angular/reusable-components-ngtemplateoutlet/
https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/