← Angular コース
63. contentChild() — 差し込まれた中身をクラスから掴む
viewChild() のレッスンでは、自分のテンプレートに書いた要素をクラスから取得しました。一方、ng-content のレッスンで学んだように、コンポーネントには親から「タグの間に差し込まれた中身」もやってきます。この差し込まれた中身は自分のテンプレートに書いたものではないので、viewChild() では取れません。そこで使うのが contentChild() と contentChildren() です。
view と content の区別を整理しておきましょう。自分の template に自分で書いたものが view、利用側が <app-tabs>...</app-tabs> のようにタグの間へ差し込んだものが content です。contentChild(TabPanelComponent) のように取りたいコンポーネントの型(またはテンプレート参照変数の名前)を指定すると、差し込まれた中からそれを探して、シグナルとして返してくれます。複数まとめて取りたいときは contentChildren() です。
この道具が活躍するのは、タブやアコーディオンのように「利用側が並べた子部品を、親が束ねて制御する」コンポーネントを作るときです。親は contentChildren() で差し込まれたパネルの一覧をシグナルで受け取り、computed でタブボタンの一覧を作る、といった具合に、これまで学んだシグナルの道具とそのまま組み合わせられます。
サンプルコード(フレームワーク環境が必要なため表示のみ)
import { Component, contentChildren, computed } from '@angular/core';
import { TabPanelComponent } from './tab-panel.component';
@Component({
selector: 'app-tabs',
// 利用側: <app-tabs><app-tab-panel title="基本"/>...</app-tabs>
template:
'@for (title of titles(); track title) {' +
' <button>{{ title }}</button>' +
'}' +
'<ng-content />',
})
export class TabsComponent {
// タグの間に差し込まれた TabPanelComponent を全部集める
panels = contentChildren(TabPanelComponent);
// シグナルなので computed とそのまま組み合わせられる
titles = computed(() => this.panels().map((p) => p.title()));
}
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗