输入只接受数字自定义指令
Input accept numbers-only custom directive
我正在尝试在 Angular2 中创建一个自定义指令,以便它仅接受数字 /^\d+$/
。到目前为止,我已经创建了一个可以实现我所需要的指令。但是...
问题:
When I try to type inside the <input>
tag the character appears for a second and then disappears.
The [(ngModel)]
which is bound to the element, updates on typing readily (while typing a number), but when a character is typed 'a || b || c, etc' it get stored in ngModel
and gets updated on typing a number.
In this way I cannot go over the <input>
characters by arrow keys, as it is bound to keyup
.
分量:
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
就可以了。
请提出实现此目的的方法,或者也欢迎任何其他更好的解决方案。
使用按键事件
@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/>
我不确定你是否能够在不改变的情况下做到这一点 html,我可以提出两个解决方案:
<input type="number" name="color" [(ngModel)]="myValue" numbers-only/
<br>
{{myValue}}
或者在组件中动态执行此操作
ngAfterViewInit() {
this.el.nativeElement.type = "number";
}
您可以创建自定义验证器并使用 Angular 的表单 API 2. 无需像您那样使用双向绑定和事件,只需创建 FormControl 的实例和 link 它到您的输入字段。在创建 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};
}
如果此函数returns为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 {}
我发现带有一个字符(长度=1)的键呈现一个字符。如果我们只想呈现数字,我们可以防止所有其他长度为 1 而不是数字(<48 或 >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();
}
}
}
我正在尝试在 Angular2 中创建一个自定义指令,以便它仅接受数字 /^\d+$/
。到目前为止,我已经创建了一个可以实现我所需要的指令。但是...
问题:
When I try to type inside the
<input>
tag the character appears for a second and then disappears.The
[(ngModel)]
which is bound to the element, updates on typing readily (while typing a number), but when a character is typed 'a || b || c, etc' it get stored inngModel
and gets updated on typing a number.In this way I cannot go over the
<input>
characters by arrow keys, as it is bound tokeyup
.
分量:
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
就可以了。
请提出实现此目的的方法,或者也欢迎任何其他更好的解决方案。
使用按键事件
@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/>
我不确定你是否能够在不改变的情况下做到这一点 html,我可以提出两个解决方案:
<input type="number" name="color" [(ngModel)]="myValue" numbers-only/
<br>
{{myValue}}
或者在组件中动态执行此操作
ngAfterViewInit() {
this.el.nativeElement.type = "number";
}
您可以创建自定义验证器并使用 Angular 的表单 API 2. 无需像您那样使用双向绑定和事件,只需创建 FormControl 的实例和 link 它到您的输入字段。在创建 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};
}
如果此函数returns为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 {}
我发现带有一个字符(长度=1)的键呈现一个字符。如果我们只想呈现数字,我们可以防止所有其他长度为 1 而不是数字(<48 或 >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();
}
}
}