Angular v18 で ng-content にフォールバックのコンテンツをサポートされます
Angular v18で入る予定の機能の紹介です。
概要
Angular では使いたいコンテンツを別のコンポーネント内に挿入または投影することができます。
具体的には ng-content
ng-container
ng-template
などのタグを利用します。
Angular v18 では ng-content
にデフォルトのコンテンツを指定できるようです。
別のコンポーネントからコンテンツが挿入されなかった場合は、デフォルトのコンテンツを表示する実装が簡単になります。
Angular v17 以前での書き方
現在の ng-content
には、デフォルトのコンテンツをフォールバックできません。
そのため、デフォルトのコンテンツを表示したい場合は自前で実装する必要があります。
実装の一例として ng-content を含む子ノードをチェックし何もコンテンツが設定されてない(= DOMが描写されていない)場合に特定のコンテンツを表示するように記述していました。
@Component({
...
template: `
<h2>Child Component</h2>
<div #ref>
<ng-content></ng-content>
</div>
<div *ngIf="ref.childNodes.length == 0">
Default Child Text
</div>
`
})
...
Angular v18 での書き方
Angular v18 ではよりシンプルになります。
ng-content の中にデフォルトのコンテンツを設定するだけです。
@Component({
...
template: `
<h2>Child Component</h2>
<ng-content>Default Child Text</ng-content>
`
})
...
Angular v17以前の書き方に比べると、余計な div タグを追加したり、DOM のチェックをする必要がなくなるので非常にわかりやすくなります。
注意点
Angularのコンテンツ投影はコンポーネントの作成時に行われます。
そのため、コンテンツの内容を動的に変更しても、デフォルトの内容は表示されません。
例えば、描写後のユーザーの行動(ボタンクリックなど)で、ifブロックがtrueからfalseになった場合はデフォルトが表示されないようです。
Note: Angular's content projection happens during creation time. This means that dynamically changing the contents of the slot will not cause the default content to show up, e.g. if a if block goes from true to false.
https://github.com/angular/angular/pull/54854
参考
ng-content の改善PR(関連 issue が立ったのは2016年なので、8年越しの嬉しい改善です)
今回紹介した内容を含むその他の Angular v18 でのリリース内容は ng-japan onair の公式動画がおすすめです
Discussion