我已根据https://auth0.com/blog/angular-2-series-part-5-forms-and-custom-validation/
实现了表单验证 <input class="form-control"
type="text"
name="phone"
autocomplete="off"
placeholder="(XXX)-XXX-XXXX"
mask=""
[disabled]="disabled"
[(ngModel)]="candidate.phone"
ngControl="phone"/>
...
...
static phone(control: Control): ValidationResult {
let URL_REGEXP = /^\(\d{3}\)-\d{3}-\d{4}$/i;
if (control.value && (control.value.length <= 5 || !URL_REGEXP.test(control.value))) {
return {"phone": true};
}
return null;
}
加上这个元素我已经实现了输入掩码目录:http://pastebin.com/wRzHSsVy
出现以下问题:输入电话号码时,首先执行验证,然后输入屏蔽目录。因此验证器检查的数据和输入掩码目录格式化的数据不同。例如,验证器上的电话号码是(888)-888-88882,掩码将数字转换为以下格式(888)-888-8888,但验证器已经工作并在掩码激活之前指出了错误。
答案 0 :(得分:0)
我有一个非常类似的问题,还有一个电话掩码/验证器。我最初的想法是在我的掩码中调用“this.control.valueAccessor.writeValue(...)”后以某种方式重新调用验证。
我的尝试是添加:
this.control.control.updateValueAndValidity(
{
onlySelf: true,
emitEvent: false
});
这似乎再次触发表单验证,但提交给验证程序的值仍然是错误的(预先屏蔽的)值。
但是,我没有在输入中使用[(ngModel)],因此您可能会使用this post suggests
之类的东西答案 1 :(得分:0)
经过一番研究后,我发现了一种解决方法。当然,感觉有点脏。
我的掩码类附加到(input)和(keyup.backspace)事件:
...
host: {
'(input)': 'onInputChange($event.target.value)',
'(keyup.backspace)': 'onInputChange($event.target.value, true)'
}
...
我没有这样做,而是附加了(模糊)和(焦点)事件。
...
host: {
'(blur)': 'onInputChange($event.target.value)',
'(focus)': 'removeMask($event.target.value)'
}
...
在焦点上,我移除了遮罩,然后在模糊处将其重新添加。这可以确保验证器在更改时获得正确的值,而不会出现屏蔽干扰。然后我将FormControl更改为使用数字验证器,而不是电话验证器,因为验证的值不会应用掩码。
电话掩码:
@Directive({
selector: '[phoneMask]',
host: {
'(blur)': 'onInputChange($event.target.value)',
'(focus)': 'removeMask($event.target.value)'
}
})
export class PhoneMask {
constructor(public control: NgControl) { }
onInputChange(value) {
// remove all mask characters (keep only numeric)
var newVal = value.replace(/\D/g, ''); // non-digits
// set the new value
this.control.valueAccessor.writeValue(PhoneMask.applyMask(newVal));
}
removeMask(value) {
this.control.valueAccessor.writeValue(value.replace(/\D/g, ''));
}
static applyMask(value: string): string {
if (value.length == 0) {
value = '';
} else if (value.length <= 3) {
value = value.replace(/^(\d{0,3})/, '($1)');
} else if (value.length <= 6) {
value = value.replace(/^(\d{0,3})(\d{0,3})/, '($1) $2');
} else {
value = value.replace(/^(\d{0,3})(\d{0,3})(.*)/, '($1) $2-$3');
}
return value;
}
}
数字验证器:
export function validateNumeric(control: FormControl) {
let regex = /[0-9]+/;
return !control.value || regex.test(control.value) ? null : { numeric: { valid: false } };
}