TIP: このガイドでは、既に基本ガイドを読んでいることを前提としています。Angularを初めて使用する場合は、まずこちらをお読みください。
Angularは、コンポーネントのセレクターに一致するすべてのHTML要素に対して、コンポーネントのインスタンスを作成します。 コンポーネントのセレクターに一致するDOM要素は、そのコンポーネントのホスト要素です。 コンポーネントのテンプレートの内容は、ホスト要素内にレンダリングされます。
// コンポーネントソース
@Component({
selector: 'profile-photo',
template: `<img src="profile-photo.jpg" alt="Your profile photo" />`,
})
export class ProfilePhoto {}
<!-- コンポーネントの使用 -->
<h3>Your profile photo</h3>
<profile-photo />
<button>Upload a new profile photo</button>
<!-- レンダリングされたDOM -->
<h3>Your profile photo</h3>
<profile-photo>
<img src="profile-photo.jpg" alt="Your profile photo" />
</profile-photo>
<button>Upload a new profile photo</button>
上記の例では、<profile-photo>はProfilePhotoコンポーネントのホスト要素です。
ホスト要素へのバインディング
コンポーネントは、ホスト要素にプロパティ、属性、スタイル、イベントをバインドできます。
これは、コンポーネントのテンプレート内の要素のバインディングと同じように動作しますが、
@Componentデコレーターのhostプロパティで定義されます。
@Component({
...,
host: {
'role': 'slider',
'[attr.aria-valuenow]': 'value',
'[class.active]': 'isActive()',
'[style.background]' : `hasError() ? 'red' : 'green'`,
'[tabIndex]': 'disabled ? -1 : 0',
'(keydown)': 'updateValue($event)',
},
})
export class CustomSlider {
value: number = 0;
disabled: boolean = false;
isActive = signal(false);
hasError = signal(false);
updateValue(event: KeyboardEvent) { /* ... */ }
/* ... */
}
NOTE: イベント名にプレフィックスとして使用できるグローバルターゲット名は document:、window:、body: です。
@HostBindingおよび@HostListenerデコレーター
クラスメンバーに@HostBindingおよび@HostListenerデコレーターを適用することにより、
ホスト要素にバインドできます。
@HostBindingを使用すると、ホストのプロパティと属性を、プロパティとゲッターにバインドできます。
@Component({
/* ... */
})
export class CustomSlider {
@HostBinding('attr.aria-valuenow')
value: number = 0;
@HostBinding('tabIndex')
get tabIndex() {
return this.disabled ? -1 : 0;
}
/* ... */
}
@HostListenerを使用すると、ホスト要素にイベントリスナーをバインドできます。
デコレーターは、イベント名とオプションの引数の配列を受け取ります。
export class CustomSlider {
@HostListener('keydown', ['$event'])
updateValue(event: KeyboardEvent) {
/* ... */
}
}
Prefer using the host property over the decorators
常に@HostBindingと@HostListenerよりもhostプロパティの使用を優先してください。
これらのデコレーターは、下位互換性のためにのみ存在します。
バインディングの衝突
テンプレートでコンポーネントを使用する場合、そのコンポーネントインスタンスの要素にバインディングを追加できます。 コンポーネントは、同じプロパティまたは属性に対するホストバインディングを定義することもあります。
@Component({
...,
host: {
'role': 'presentation',
'[id]': 'id',
}
})
export class ProfilePhoto { /* ... */ }
<profile-photo role="group" [id]="otherId" />
このような場合、以下のルールによってどの値が優先されるかが決まります。
- 両方の値が静的な場合、インスタンスバインディングが優先されます。
- 一方の値が静的で他方が動的な場合、動的な値が優先されます。
- 両方の値が動的な場合、コンポーネントのホストバインディングが優先されます。
CSSカスタムプロパティを使用したスタイリング
開発者は、コンポーネントのスタイルを柔軟に設定できるようにするために、CSSカスタムプロパティに頼ることがよくあります。 このようなカスタムプロパティは、スタイルバインディングを使用してホスト要素に設定できます。
@Component({
/* ... */
host: {
'[style.--my-background]': 'color()',
},
})
export class MyComponent {
color = signal('lightgreen');
}
この例では、--my-background CSSカスタムプロパティがcolorシグナルにバインドされています。カスタムプロパティの値は、colorシグナルが変更されるたびに自動的に更新されます。これは現在のコンポーネントと、このカスタムプロパティに依存するすべての子コンポーネントに影響します。
子コンポーネントでのカスタムプロパティの設定
また、スタイルバインディングを使用して、子コンポーネントのホスト要素にCSSカスタムプロパティを設定できます。
@Component({
selector: 'my-component',
template: `<my-child [style.--my-background]="color()" />`,
})
export class MyComponent {
color = signal('lightgreen');
}
ホスト要素の属性の注入
コンポーネントとディレクティブは、inject関数とともにHostAttributeTokenを使用して、ホスト要素から静的属性を読み取ることができます。
import { Component, HostAttributeToken, inject } from '@angular/core';
@Component({
selector: 'app-button',
...,
})
export class Button {
variation = inject(new HostAttributeToken('variation'));
}
<app-button variation="primary">Click me</app-button>
HELPFUL: HostAttributeTokenは、注入がオプションとしてマークされていない限り、属性が欠けている場合にエラーをスローします。