检测指令中输入值何时更改

nco*_*hen 31 angular-directive angular2-directives angular

我正试图检测指令中输入何时发生变化.我有以下指令:

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');
    }
}
Run Code Online (Sandbox Code Playgroud)

该指令中的问题是它仅在存在输入时检测,而不是在以编程方式更改值时检测.我使用重新形式,有时我用patchValue()函数设置值.我该怎么做才能触发更改功能?

Ted*_*rne 49

您需要创建一个输入属性,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');
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

Plunkr


Cri*_*ìna 11

有一种更好的方法来检测Input属性何时发生变化,它被认为是最佳实践,并且也用于*ngIf实现中

你只需要推迟关键词setInput(),这样你结合@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;
}
Run Code Online (Sandbox Code Playgroud)

如果要将新值与先前值进行比较,则必须将变量存储在类属性中,并在第二次调用该方法时检索它:

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;  
}
Run Code Online (Sandbox Code Playgroud)


Ash*_*lue 8

从 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);
    }
  }
Run Code Online (Sandbox Code Playgroud)


Tus*_*osh 5

您还可以使用 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');
    }

}
Run Code Online (Sandbox Code Playgroud)

  • “更改”不起作用,“mouseenter”、“mouseleave”来自角度示例工作。请测试你的答案。 (5认同)
  • 'change' 至少适用于选择菜单('ngModelChange' 也是如此,您可以通过注入 `$event` var 来获取新值:`@HostListener('ngModelChange', ['$event']) public doStuff (值){...}`) (4认同)