属性ディレクティブを使用して、DOM要素とAngularコンポーネントの外観や動作を変更します。
属性ディレクティブの作成
このセクションでは、ホスト要素の背景色を黄色に設定するハイライトディレクティブを作成する方法について説明します。
ディレクティブを作成するには、CLIコマンド
ng generate directive
を使用します。ng generate directive highlight
CLIは
src/app/highlight.directive.ts
と、対応するテストファイルsrc/app/highlight.directive.spec.ts
を作成します。src/app/highlight.directive.ts
import {Directive} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective {}
@Directive()
デコレーターの構成プロパティは、ディレクティブのCSS属性セレクター[appHighlight]
を指定します。@angular/core
からElementRef
をインポートします。ElementRef
は、nativeElement
プロパティを通じてホストDOM要素(appHighlight
を適用する要素)への直接アクセスを提供します。ディレクティブの
constructor()
にElementRef
を追加して、ホストDOM要素への参照を注入します。背景を黄色に設定するロジックを
HighlightDirective
クラスに追加します。src/app/highlight.directive.ts
import {Directive, ElementRef} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { constructor(private el: ElementRef) { this.el.nativeElement.style.backgroundColor = 'yellow'; }}
HELPFUL: ディレクティブはネームスペースをサポートしていません。
src/app/app.component.avoid.html (unsupported)
<p app:Highlight>This is invalid</p>
属性ディレクティブの適用
HighlightDirective
を使用するには、ディレクティブを属性として持つ<p>
要素をHTMLテンプレートに追加します。src/app/app.component.html
<h1>My First Attribute Directive</h1><p appHighlight>Highlight me!</p><p appHighlight="yellow">Highlighted in yellow</p><p [appHighlight]="'orange'">Highlighted in orange</p><p [appHighlight]="color">Highlighted with parent component's color</p>
AngularはHighlightDirective
クラスのインスタンスを作成し、<p>
要素への参照をディレクティブのコンストラクターに注入します。これにより、<p>
要素の背景スタイルが黄色に設定されます。
ユーザーイベントの処理
このセクションでは、ユーザーが要素内または要素外にマウスを移動したときに検出する方法と、ハイライトカラーを設定またはクリアして応答する方法について説明します。
@angular/core
からHostListener
をインポートします。src/app/highlight.directive.ts (imports)
import {Directive, ElementRef, HostListener} from '@angular/core';import {Input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { constructor(private el: ElementRef) {} @HostListener('mouseenter') onMouseEnter() { this.highlight('yellow'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
マウスが入りまたは出たときに応答する2つのイベントハンドラーを追加します。それぞれに
@HostListener()
デコレーターを使用します。src/app/highlight.directive.ts (mouse-methods)
import {Directive, ElementRef, HostListener} from '@angular/core';import {Input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { constructor(private el: ElementRef) {} @HostListener('mouseenter') onMouseEnter() { this.highlight('yellow'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
@HostListener()
デコレーターを使用して、属性ディレクティブをホストするDOM要素(この場合は<p>
)のイベントを購読します。
HELPFUL: ハンドラーは、ホストDOM要素el
に色を設定するヘルパーメソッドhighlight()
に委任します。
完全なディレクティブは次のとおりです。
src/app/highlight.directive.ts
import {Directive, ElementRef, HostListener} from '@angular/core';import {Input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { constructor(private el: ElementRef) {} @HostListener('mouseenter') onMouseEnter() { this.highlight('yellow'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
ポインタが段落要素の上にホバーすると背景色が表示され、ポインタが外れると背景色が消えます。
属性ディレクティブに値を渡す
このセクションでは、HighlightDirective
を適用するときにハイライトカラーを設定する方法について説明します。
highlight.directive.ts
で、@angular/core
からInput
をインポートします。src/app/highlight.directive.ts (imports)
import {Directive, ElementRef, HostListener, Input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { constructor(private el: ElementRef) {} @Input() appHighlight = ''; @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
appHighlight
@Input()
プロパティを追加します。src/app/highlight.directive.ts
import {Directive, ElementRef, HostListener, Input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { constructor(private el: ElementRef) {} @Input() appHighlight = ''; @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
@Input()
デコレーターは、ディレクティブのappHighlight
プロパティをバインディングで使用できるようにするメタデータをクラスに追加します。app.component.ts
で、AppComponent
にcolor
プロパティを追加します。src/app/app.component.ts (class)
import {Component} from '@angular/core';import {HighlightDirective} from './highlight.directive';@Component({ selector: 'app-root', templateUrl: './app.component.1.html', imports: [HighlightDirective],})export class AppComponent { color = 'yellow';}
ディレクティブと色を同時に適用するには、
appHighlight
ディレクティブセレクターを使用してプロパティバインディングを使用し、それをcolor
に設定します。src/app/app.component.html (color)
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr /><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr /><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>
[appHighlight]
属性バインディングは次の2つのタスクを実行します。<p>
要素にハイライトディレクティブを適用する- プロパティバインディングを使用してディレクティブのハイライトカラーを設定する
ユーザー入力を使用して値を設定する
このセクションでは、カラー選択をappHighlight
ディレクティブにバインドするラジオボタンを追加する方法について説明します。
色を選択するためのマークアップを
app.component.html
に追加します。src/app/app.component.html (v2)
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr /><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr /><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>
AppComponent.color
を修正して、初期値を持たないようにします。src/app/app.component.ts (class)
import {Component} from '@angular/core';import {HighlightDirective} from './highlight.directive';@Component({ selector: 'app-root', templateUrl: './app.component.html', imports: [HighlightDirective],})export class AppComponent { color = '';}
highlight.directive.ts
で、onMouseEnter
メソッドを修正して、最初にappHighlight
でハイライトしようとします。appHighlight
がundefined
の場合はred
にフォールバックします。src/app/highlight.directive.ts (mouse-enter)
import {Directive, ElementRef, HostListener, Input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { constructor(private el: ElementRef) {} @Input() appHighlight = ''; @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
アプリケーションを起動して、ユーザーがラジオボタンで色を選択できることを確認します。
2番目のプロパティにバインドする
このセクションでは、開発者がデフォルトカラーを設定できるようにアプリケーションを構成する方法について説明します。
HighlightDirective
にdefaultColor
という名前の2番目のInput()
プロパティを追加します。src/app/highlight.directive.ts (defaultColor)
import {Directive, ElementRef, HostListener, Input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { constructor(private el: ElementRef) {} @Input() defaultColor = ''; @Input() appHighlight = ''; @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight || this.defaultColor || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
ディレクティブの
onMouseEnter
を修正して、最初にappHighlight
でハイライトしようとします。次にdefaultColor
でハイライトしようとします。両方のプロパティがundefined
の場合はred
にフォールバックします。src/app/highlight.directive.ts (mouse-enter)
import {Directive, ElementRef, HostListener, Input} from '@angular/core';@Directive({ selector: '[appHighlight]',})export class HighlightDirective { constructor(private el: ElementRef) {} @Input() defaultColor = ''; @Input() appHighlight = ''; @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight || this.defaultColor || 'red'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }}
AppComponent.color
にバインドし、デフォルトカラーとして「violet」を使用するには、次のHTMLを追加します。 この場合、defaultColor
バインディングは、静的であるため、角括弧[]
を使用しません。src/app/app.component.html (defaultColor)
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr /><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr /><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>
コンポーネントと同様に、ホスト要素に複数のディレクティブプロパティバインディングを追加できます。
デフォルトカラーは、デフォルトカラーバインディングがない場合は赤です。 ユーザーが色を選択すると、選択した色がアクティブなハイライトカラーになります。
NgNonBindable
を使用してAngularの処理を無効にする
ブラウザでの式評価を防ぐには、ホスト要素にngNonBindable
を追加します。
ngNonBindable
は、テンプレート内の補間、ディレクティブ、バインディングを無効にします。
次の例では、式{{ 1 + 1 }}
はコードエディタと同じようにレンダリングされ、2
は表示されません。
src/app/app.component.html
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr /><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr /><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>
ngNonBindable
を要素に適用すると、その要素の子要素のバインディングが停止します。
ただし、ngNonBindable
は、ngNonBindable
を適用した要素に対しては、ディレクティブを動作させます。
次の例では、appHighlight
ディレクティブはアクティブですが、Angularは式{{ 1 + 1 }}
を評価しません。
src/app/app.component.html
<h1>My First Attribute Directive</h1><h2>Pick a highlight color</h2><div> <input type="radio" name="colors" (click)="color='lightgreen'">Green <input type="radio" name="colors" (click)="color='yellow'">Yellow <input type="radio" name="colors" (click)="color='cyan'">Cyan</div><p [appHighlight]="color">Highlight me!</p><p [appHighlight]="color" defaultColor="violet"> Highlight me too!</p><hr /><h2>Mouse over the following lines to see fixed highlights</h2><p [appHighlight]="'yellow'">Highlighted in yellow</p><p appHighlight="orange">Highlighted in orange</p><hr /><h2>ngNonBindable</h2><p>Use ngNonBindable to stop evaluation.</p><p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p><h3>ngNonBindable with a directive</h3><div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.</div>
ngNonBindable
を親要素に適用すると、Angularは要素の子要素に対して、プロパティバインディングやイベントバインディングなどあらゆる種類の補間とバインディングを無効にします。