输入仅接受数字的自定义指令

时间:2016-11-06 11:30:59

标签: javascript angular angular-ngmodel

我试图在Angular2中创建自定义指令,因此它只接受数字/^\d+$/。到目前为止,我已经创建了一个实现我需要的指令。但...

问题:

  
      
  1. 当我尝试在<input>标签内输入时,该字符会出现一秒钟然后消失。

  2.   
  3. 绑定到元素的[(ngModel)],在输入时更新(在键入数字时),但是当输入一个字符&#39; a ||时b || c等等#39;它存储在ngModel中,并在输入数字时获得最新信息。

  4.   
  5. 通过这种方式,我无法通过箭头键检查<input>个字符,因为它绑定到keyup

  6.   

组件:

export class AppComponent {
  myValue = 123;
}

HTML:

<input type="text" name="color" [(ngModel)]="myValue" numbers-only/> <br>
{{myValue}}

指令:

@Directive({
  selector: '[numbers-only]', 
    host: {
        '(keyup)' : 'onInputChange()'
    }
})
export class UpperCaseDirective {
  private oldVal = '';
  @Input() ngModel: any;

  constructor(private el: ElementRef) { }

  ngOnInit() {
    this.oldVal = this.ngModel || '';
  }

  onInputChange() {
    console.log(this.ngModel, !isNaN(this.ngModel));
    var reg = /^\d+$/;
    if (reg.test(this.ngModel)) {      
      this.el.nativeElement.value = this.ngModel;
      this.oldVal = this.ngModel;
    } else {
      this.el.nativeElement.value = this.oldVal;
    }
  }

}

从一个Angular1背景开始,我发现很难为一个简单的数字编写这么多代码<input>ng-pattern就可以了。

请建议一种方法来实现这一点,或者欢迎任何其他更好的解决方案。

4 个答案:

答案 0 :(得分:1)

使用按键事件

@HostListener('keypress') onkeypress(e){
        let event = e || window.event;
        if(event){
          return this.isNumberKey(event);
        }
      }

  isNumberKey(event){
     let charCode = (event.which) ? event.which : event.keyCode;
     if (charCode > 31 && (charCode < 48 || charCode > 57)){
        return false;
     }
     return true;
  }


<input type="text" name="color" [(ngModel)]="myValue" appUpperCase/>

答案 1 :(得分:0)

我不确定你是否能够在不改变html的情况下做到这一点,我可以提出两个解决方案:

ngAfterViewInit() {
  this.el.nativeElement.type = "number";
}

或者在组件中动态执行此操作

vendor/

答案 2 :(得分:0)

您可以创建自定义验证器并使用Angular 2的Forms API。不要像使用双向绑定和事件那样,只需创建FormControl的实例并将其链接到输入字段。在创建FormControl的实例时,为其分配自定义验证器,即将验证输入的函数。例如,这是允许只输入正数的方法:

function positiveNumberValidator(control: FormControl): any {
  if (!control.value) return null;
  const price = parseInt(control.value);
  return price === null ||
  typeof price === 'number' &&
  price > 0 ? null : {positivenumber: true};
}

如果此函数返回null,则表示该值有效。您可以在此处查看在SearchComponent中实现的此示例:https://github.com/Farata/angular2typescript/tree/master/chapter8/auction/client/app/components/search

该示例使用FormBuilder API,但您只需声明一个变量,实例化该对象并分配验证器:

let price: FormControl = new FormControl('', positiveNumberValidator);

如果要将验证器包装到指令中,可以这样做:

@Directive({
     
    selector: '[numbers-only]',
      
    providers: [{provide: NG_VALIDATORS, 
                         useValue: positiveNumberValidator}]

    })
    
class NumberValidatorDirective {}

答案 3 :(得分:0)

我发现带有一个char(length = 1)的键会呈现一个char。如果我们只想渲染数字,我们可以阻止长度为1且不是数字(&lt; 48或&gt; 57)的所有其他密钥的默认值:

import {Directive, ElementRef, HostListener} from '@angular/core';

@Directive({
    selector: '[numbers-only]'
})
export class NumbersOnlyDirective {
    @HostListener('keydown', ['$event'])
    keyDownEvent(event: KeyboardEvent) {
        if (event.key.length === 1 && (event.which < 48 || event.which > 57)) {
            event.preventDefault();
        }
    }

}