入力のvalueがディレクティブで変更されたことを検出しようとしています。次のディレクティブがあります。
import { ElementRef, Directive, Renderer} from '@angular/core';
@Directive({
selector: '[number]',
Host: {"(input)": 'onInputChange($event)'}
})
export class Number {
constructor(private element: ElementRef, private renderer: Renderer){
}
onInputChange(event){
console.log('test');
}
}
このディレクティブの問題は、値がプログラム的に変更されたときではなく、入力があるときのみ検出することです。私はreaciveフォームを使用し、時々patchValue()
関数で値を設定します。変更機能がトリガーされるようにするにはどうすればよいですか?
input
の入力プロパティを作成してから、ngOnChanges
フックを使用して、入力プロパティが変更されたことを通知する必要があります。
@Directive({
selector: '[number]'
})
export class NumberDirective implements OnChanges {
@Input() public number: any;
@Input() public input: any;
ngOnChanges(changes: SimpleChanges){
if(changes.input){
console.log('input changed');
}
}
}
この結果を使用するより良い方法があります。たとえば、*ngIf
Angular source code で使用されます。
@Input()
とsetter
を組み合わせることができます。入力が変更されると、セッターが再度呼び出されます。
@Input() set numberOfWheels(wheels: number) {
if(wheels === 2) {
console.log("It's a bike!");
}
else if(wheels === 4) {
console.log("It's a car!");
}
else {
console.log("I don't know what it is :(");
}
}
以前の値をDirectiveプロパティに保存して後で使用し、新しい値と比較することができます。
private previousValue: any = null;
@Input() set myInputName(value: any) {
console.log(`Previous value is: ${this.previousValue}`);
console.log(`New value is: ${value}`);
this.previousValue = value;
}
HostListenerを使用することもできます。 HostListenerの詳細については、 このリンク をご覧ください。これがコードです。
import {Directive, ElementRef, HostListener} from '@angular/core';
@Directive({
selector: '[number]'
})
export class NumberDirective {
@Input() public number: any;
@Input() public input: any;
constructor(private el: ElementRef) {}
@HostListener('change') ngOnChanges() {
console.log('test');
}
}