为什么 ng-pattern 无法正确验证来自非用户输入事件的更改?
Why ng-pattern won't validate correctly on changes from a non user input event?
我将这些输入放在一个表单中,我正在使用 angular 的 ng-pattern
、ng-required
和 ng-model
指令进行验证:
<div class="form-group">
<div style="padding-left:0px;" ng-class="{'has-error':personalDataForm.phone.$invalid && personalDataForm.phone.$dirty}" class="col-md-6">
<label>Teléfono</label>
<input type="text" name="phone" ng-pattern="/[0-9]{3}-[0-9]{7}/" ng-required="true" ng-trim="true" ng-model="phone" class="form-control phoneRegexInput"/>
</div>
<div style="padding-left:0px;" ng-class="{'has-error':personalDataForm.mobile.$invalid && personalDataForm.mobile.$dirty}" class="col-md-6">
<label>Celular</label>
<input type="text" name="mobile" ng-pattern="/[0-9]{3}-[0-9]{7}/" ng-required="true" ng-trim="true" ng-model="mobile" class="form-control phoneRegexInput"/>
</div>
</div>
因此 ng-pattern
指令将查找格式为 7 位数字前缀为 3 位数字和连字符 的字符串,例如:287-8719423.
因为我不想强迫用户输入连字符,所以我得到了一个 jQuery 函数,它会在输入完成 3 个必需的数字后放置连字符,这是我的函数:
$(".phoneRegexInput").keyup(function() {
var phone = $(this).val();
console.log(phone + " didnt match");
if (phone.match(/\d{10}/)) {
phone = phone.substr(0, 3) + "" + '-' + phone.substr(3);
console.log(phone);
$(this).val(phone);
}
});
它工作正常,它实际上将输入值更改为格式正确的值,但它不会验证它是否正确。如果我删除并再次输入正确的输入,它就会。
所以我认为这是因为验证是从实际用户输入触发的,我怎样才能让它从任何更改中监听?
相关问题。
我知道这可能与this question有关,但问题是model
赢了两者都不更改,因为它无效。
我该如何解决?
解决方法
我想,"change the model",所以我试了:
$(".phoneRegexInput").keyup(function() {
var phone = $(this).val();
console.log(phone + " didnt match");
if (phone.match(/\d{10}/)) {
phone = phone.substr(0, 3) + "" + '-' + phone.substr(3);
console.log(phone);
// Attempt to change model
if ($scope.personalData)
$scope.personalData.phone = phone;
else {
$scope.personalData = {
phone: phone
}
}
console.log($scope.personalData);
}
});
但现在更奇怪的事情发生了,登录时我可以看到一个实际对象 $scope.personalData
但如果我尝试在标记处通过 {{personalData}} 进行调试,它似乎没有属性.
没关系,我必须让验证后台监视或监听模型的变化。
我建议使用带有解析器和格式化程序的指令为 phone 个数字创建您自己的验证
'use strict';
angular
.module('MyApp',[])
.directive('input', inputTel);
var NANP_REGEXP = /^([0-9]{3})([0-9]{7})$/;
function inputTel() {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, elem, attr, ctrl) {
if (ctrl && attr.type === 'tel') {
ctrl.$parsers.push(function (viewValue) {
if(ctrl.$isEmpty(viewValue)){
ctrl.$setValidity('tel', true);
return viewValue;
}
var numbers = viewValue? viewValue.replace(/\D/g, "") : '';
if (NANP_REGEXP.test(numbers)) {
var formatted = numbers.replace(NANP_REGEXP, '-');
if (formatted !== viewValue) {
ctrl.$setViewValue(formatted);
ctrl.$render();
}
ctrl.$setValidity('tel', true);
return numbers.replace(NANP_REGEXP, '');
} else {
ctrl.$setValidity('tel', false);
return undefined;
}
});
ctrl.$formatters.push(function (viewValue) {
if(ctrl.$isEmpty(viewValue)){
ctrl.$setValidity('tel', true);
return viewValue;
}
var numbers = ctrl.$modelValue? ctrl.$modelValue.replace(/\D/g, "") : '';
if (NANP_REGEXP.test(numbers)) {
ctrl.$setValidity('tel', true);
return numbers.replace(NANP_REGEXP, '-');
} else {
ctrl.$setValidity('tel', false);
return undefined;
}
});
}
}
};
}
演示 http://jsfiddle.net/TheSharpieOne/qhphg0ax/1/
注意:我使用 HTML5 输入 type=tel 来帮助确定此验证适用于哪些输入。此验证还允许用户看到格式化的输入,同时保持内部值只是数字。
这也暴露了 'tel' 在 formName.fieldName.$error.tel
的自定义验证错误
我将这些输入放在一个表单中,我正在使用 angular 的 ng-pattern
、ng-required
和 ng-model
指令进行验证:
<div class="form-group">
<div style="padding-left:0px;" ng-class="{'has-error':personalDataForm.phone.$invalid && personalDataForm.phone.$dirty}" class="col-md-6">
<label>Teléfono</label>
<input type="text" name="phone" ng-pattern="/[0-9]{3}-[0-9]{7}/" ng-required="true" ng-trim="true" ng-model="phone" class="form-control phoneRegexInput"/>
</div>
<div style="padding-left:0px;" ng-class="{'has-error':personalDataForm.mobile.$invalid && personalDataForm.mobile.$dirty}" class="col-md-6">
<label>Celular</label>
<input type="text" name="mobile" ng-pattern="/[0-9]{3}-[0-9]{7}/" ng-required="true" ng-trim="true" ng-model="mobile" class="form-control phoneRegexInput"/>
</div>
</div>
因此 ng-pattern
指令将查找格式为 7 位数字前缀为 3 位数字和连字符 的字符串,例如:287-8719423.
因为我不想强迫用户输入连字符,所以我得到了一个 jQuery 函数,它会在输入完成 3 个必需的数字后放置连字符,这是我的函数:
$(".phoneRegexInput").keyup(function() {
var phone = $(this).val();
console.log(phone + " didnt match");
if (phone.match(/\d{10}/)) {
phone = phone.substr(0, 3) + "" + '-' + phone.substr(3);
console.log(phone);
$(this).val(phone);
}
});
它工作正常,它实际上将输入值更改为格式正确的值,但它不会验证它是否正确。如果我删除并再次输入正确的输入,它就会。
所以我认为这是因为验证是从实际用户输入触发的,我怎样才能让它从任何更改中监听?
相关问题。
我知道这可能与this question有关,但问题是model
赢了两者都不更改,因为它无效。
我该如何解决?
解决方法
我想,"change the model",所以我试了:
$(".phoneRegexInput").keyup(function() {
var phone = $(this).val();
console.log(phone + " didnt match");
if (phone.match(/\d{10}/)) {
phone = phone.substr(0, 3) + "" + '-' + phone.substr(3);
console.log(phone);
// Attempt to change model
if ($scope.personalData)
$scope.personalData.phone = phone;
else {
$scope.personalData = {
phone: phone
}
}
console.log($scope.personalData);
}
});
但现在更奇怪的事情发生了,登录时我可以看到一个实际对象 $scope.personalData
但如果我尝试在标记处通过 {{personalData}} 进行调试,它似乎没有属性.
没关系,我必须让验证后台监视或监听模型的变化。
我建议使用带有解析器和格式化程序的指令为 phone 个数字创建您自己的验证
'use strict';
angular
.module('MyApp',[])
.directive('input', inputTel);
var NANP_REGEXP = /^([0-9]{3})([0-9]{7})$/;
function inputTel() {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, elem, attr, ctrl) {
if (ctrl && attr.type === 'tel') {
ctrl.$parsers.push(function (viewValue) {
if(ctrl.$isEmpty(viewValue)){
ctrl.$setValidity('tel', true);
return viewValue;
}
var numbers = viewValue? viewValue.replace(/\D/g, "") : '';
if (NANP_REGEXP.test(numbers)) {
var formatted = numbers.replace(NANP_REGEXP, '-');
if (formatted !== viewValue) {
ctrl.$setViewValue(formatted);
ctrl.$render();
}
ctrl.$setValidity('tel', true);
return numbers.replace(NANP_REGEXP, '');
} else {
ctrl.$setValidity('tel', false);
return undefined;
}
});
ctrl.$formatters.push(function (viewValue) {
if(ctrl.$isEmpty(viewValue)){
ctrl.$setValidity('tel', true);
return viewValue;
}
var numbers = ctrl.$modelValue? ctrl.$modelValue.replace(/\D/g, "") : '';
if (NANP_REGEXP.test(numbers)) {
ctrl.$setValidity('tel', true);
return numbers.replace(NANP_REGEXP, '-');
} else {
ctrl.$setValidity('tel', false);
return undefined;
}
});
}
}
};
}
演示 http://jsfiddle.net/TheSharpieOne/qhphg0ax/1/
注意:我使用 HTML5 输入 type=tel 来帮助确定此验证适用于哪些输入。此验证还允许用户看到格式化的输入,同时保持内部值只是数字。
这也暴露了 'tel' 在 formName.fieldName.$error.tel