检测指令中的输入值何时更改
Detect when input value changed in directive
我正在尝试检测输入的值 何时在指令中更改。我有以下指令:
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');
}
}
此指令中的问题是它仅在有输入时检测,而不是在值以编程方式更改时检测。我使用反应形式,有时我使用 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');
}
}
}
Plunkr
Stackblitz
您也可以使用 HostListener。有关 HostListener 的更多信息,您可以浏览 this link。这是代码。
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');
}
}
有一种更好的方法来检测 Input
属性 何时发生变化,它被认为是最佳实践,它也用于 *ngIf
implementation。
你只需要在 Input()
之后推迟关键字 set
,这样你就可以将 @Input()
装饰器与 setter
结合起来,它会被调用所有值变化的倍数。
_rows: number;
@Input() set rows(value: number) {
if (this.value < 0) {
console.error('The number of rows must be positive');
this._rows = 2;
return;
}
this._rows = value;
}
如果要将新值与先前值进行比较,必须将变量存储在 class 属性 中,并在第二次调用该方法时检索它:
private previousValue: any = T;
@Input() set myInputName(value: T) {
console.log(`Previous value was: ${this.previousValue}`);
console.log(`New value is: ${value}`);
this.previousValue = value;
}
截至 Angular 9+ 我可以验证下面的代码片段是正确的解决方案。出于多种原因,最好尽可能避免 ngOnChanges
并改用正确的主机侦听器事件。下面的示例将获取 keyup
上的当前输入值。您可以根据输入指令的需要轻松自定义此代码段。
@Directive({
selector: '[appMyDirective]',
})
export class MyDirective {
// Add whatever event you want to track here
@HostListener('keyup', ['$event']) public onKeyup(event: KeyboardEvent): void {
const value = (event.target as HTMLInputElement).value;
console.log(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');
}
}
此指令中的问题是它仅在有输入时检测,而不是在值以编程方式更改时检测。我使用反应形式,有时我使用 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');
}
}
}
Plunkr
Stackblitz
您也可以使用 HostListener。有关 HostListener 的更多信息,您可以浏览 this link。这是代码。
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');
}
}
有一种更好的方法来检测 Input
属性 何时发生变化,它被认为是最佳实践,它也用于 *ngIf
implementation。
你只需要在 Input()
之后推迟关键字 set
,这样你就可以将 @Input()
装饰器与 setter
结合起来,它会被调用所有值变化的倍数。
_rows: number;
@Input() set rows(value: number) {
if (this.value < 0) {
console.error('The number of rows must be positive');
this._rows = 2;
return;
}
this._rows = value;
}
如果要将新值与先前值进行比较,必须将变量存储在 class 属性 中,并在第二次调用该方法时检索它:
private previousValue: any = T;
@Input() set myInputName(value: T) {
console.log(`Previous value was: ${this.previousValue}`);
console.log(`New value is: ${value}`);
this.previousValue = value;
}
截至 Angular 9+ 我可以验证下面的代码片段是正确的解决方案。出于多种原因,最好尽可能避免 ngOnChanges
并改用正确的主机侦听器事件。下面的示例将获取 keyup
上的当前输入值。您可以根据输入指令的需要轻松自定义此代码段。
@Directive({
selector: '[appMyDirective]',
})
export class MyDirective {
// Add whatever event you want to track here
@HostListener('keyup', ['$event']) public onKeyup(event: KeyboardEvent): void {
const value = (event.target as HTMLInputElement).value;
console.log(value);
}
}