检测指令

时间:2017-01-18 19:39:56

标签: angular angular-directive angular2-directives

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

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()函数设置值。我该怎么做才能触发更改功能?

4 个答案:

答案 0 :(得分:41)

您需要创建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

答案 1 :(得分:4)

从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);
    }
  }

答案 2 :(得分:2)

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

}

答案 3 :(得分:1)

有一种更好的方法可以使用此结果,例如在*ngIf Angular source code中使用。

您可以将@Input()setter合并。当输入改变时,再次调用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;  
}