为什么ng模式获胜't对来自非用户输入事件的更改进行正确验证

Why ng-pattern won't validate correctly on changes from a non user input event?

本文关键字:入事件 输入 验证 用户 获胜 模式 ng 为什么      更新时间:2023-12-31

我在一个表单中有这些输入,我正在用angular的ng-patternng-requiredng-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);
    }
});

它工作正常,实际上它将输入值更改为格式正确的值,但它不会验证它是否正确。如果我删除并再次键入正确的输入,它会的。

所以我认为这是因为验证是从实际用户输入中启动的,我如何让它从任何更改中侦听?

相关问题

我知道这可能与这个问题有关,但问题是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);
    }
});

但现在发生了更奇怪的事情,我可以在loggin时看到一个实际的对象为$scope.personalData,但如果我试图在标记时通过{{personalData}}进行调试,它似乎没有该属性。

无论如何,我必须让验证后台监视或侦听模型的更改。

我建议使用带有解析器和格式化程序的指令创建自己的电话号码验证

"严格使用";

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, '$1-$2');
                        if (formatted !== viewValue) {
                            ctrl.$setViewValue(formatted);
                            ctrl.$render();
                        }
                        ctrl.$setValidity('tel', true);
                        return numbers.replace(NANP_REGEXP, '$1$2');
                    } 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, '$1-$2');
                    } else {
                        ctrl.$setValidity('tel', false);
                        return undefined;
                    }
                });
            }
        }
    };
}

Demohttp://jsfiddle.net/TheSharpieOne/qhphg0ax/1/

注意:我使用HTML5 input-type=tel来帮助确定此验证适用于哪些输入。此外,此验证可以让用户看到格式化的输入,同时只保留数字的内部值。

这也暴露了formName.fieldName.$error.tel 上"tel"的自定义验证错误