導入
レッスン6で使った *ngIf/*ngFor は、Angularがあらかじめ用意した「構造ディレクティブ」でした。実は、ディレクティブとパイプは自分で作ることもできます。表示のたびに繰り返す「値の変換」はパイプに、要素に付け足す「振る舞い」はディレクティブにまとめると、テンプレートがすっきりします。
説明
パイプは {{ 値 | パイプ名 }} の形でテンプレートに書き、transform() メソッドで値を変換します。ディレクティブは要素の属性として書き、@HostListener/@HostBinding でその要素自身のイベントや見た目を扱います。
@Pipe({ name: 'yen', standalone: true })
class YenPipe {
transform(value: number): string {
return '¥' + value.toLocaleString();
}
}
@Directive({ selector: '[appHighlight]', standalone: true })
class HighlightDirective {
@HostBinding('style.backgroundColor') bg = '';
@HostListener('mouseenter') onEnter(): void {
this.bg = '#fff3bf';
}
@HostListener('mouseleave') onLeave(): void {
this.bg = '';
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [YenPipe, HighlightDirective],
template: `
<p appHighlight>マウスを乗せると色が変わります</p>
<p>価格: {{ price | yen }}</p>
`,
})
class AppComponent {
price = 1980;
}
@Pipe({ name: 'yen', standalone: true })のtransform(value)が変換ロジックです。{{ price | yen }}のように|の右にパイプ名を書いて使います。@Directive({ selector: '[appHighlight]', standalone: true })は属性として使う自作ディレクティブです。要素にappHighlightと書くだけで振る舞いが追加されます。@HostListener('mouseenter')… このディレクティブが付いた要素で起きたイベントを拾います。@HostBinding('style.backgroundColor')… このディレクティブが付いた要素自身のプロパティを書き換えます。- パイプもディレクティブも
standalone: trueを付け、使うコンポーネントのimportsに登録すれば使えます(Componentと同じ要領です)。
やってみよう
YenPipeをまねて、数値を「◯個」という文字列に変換するCountPipeを作ってみましょう。HighlightDirectiveを<p>だけでなく<button>にもappHighlightとして付けて、同じ振る舞いが再利用できることを確かめましょう。