Directive not called on input change

2019-07-07 16:57发布

I'm facing an issue which I can't seem to solve. I have several inputs with each a directive to validate the input value, like this:

<div class="row form-group">
        <div class="col-sm-6">last name</div>
        <div class="col-sm-6">
            <div class="input-group" ng-class="{'has-error': form.lastname.$invalid && (form.lastname.$touched || form.$submitted)}">
                <input type="text" name="lastname" class="form-control"
                       model-blur
                       validator-lastname
                       ng-trim="true"
                       ng-model="fields.lastname.value"
                       ng-maxlength="fields.lastname.validation.maxLength">
                <input-group-addon class="input-group-addon"
                                       iga-char=""
                                       iga-form="form"
                                       iga-field="form.lastname"
                                       iga-if-touched="true">
                </input-group-addon> 
            </div>

            <form-message-list fml-form="form"
                                   fml-field="form.lastname"
                                   fml-label="Last name"
                                   fml-fieldData="fields.lastname">
            </form-message-list>
        </div>
    </div>

This field required the following pattern: /^[\'a-zA-Z_]+( [\'a-zA-Z_]+)*$/

My issue is this: When I add an invalid value to my input, like this: / , my invalid message remains and ng-invalid-pattern remains on my field.

When I add this pattern to my field like this: ng-pattern="/^[\'a-zA-Z_]+( [\'a-zA-Z_]+)*$/" I don't have any issues. But when I try to validate via my directive validator-lastname it only checks one time. When I fill the input with an invalid value and then change it to empty, which is allowed, the ng-invalid-pattern error remains.

This is my directive:

angular.module('app')
    .directive('validatorLastname', validatorLastname);

/* @ngInject */
function validatorLastname() {

    var directive = {
        require: 'ngModel',
        link: link
    };

    return directive;

    function link(scope, element, attrs, modelCtrl) {

        var valid = false;

        var formatter = function (inputValue) {
            if (inputValue) {
                var res = inputValue.match(/^[\'a-zA-Z_]+( [\'a-zA-Z_]+)*$/);
                if (res && res.length > 0) {
                    valid = true;
                }

                modelCtrl.$setValidity('pattern', valid);
                valid = false;
            }
            return inputValue;
        };
        modelCtrl.$parsers.push(formatter);
        if (scope[attrs.ngModel] && scope[attrs.ngModel] !== '') {
            formatter(scope[attrs.ngModel]);
        }
    }
}

I made a JSFiddle to reproduce the problem: http://jsfiddle.net/sZZEt/537/

I hope someone can point me in the right direction. Thanks in advance.

1条回答
smile是对你的礼貌
2楼-- · 2019-07-07 17:49

You should update your directive code to make everything work fine.

angular.module('app')
.directive('validatorLastname', validatorLastname);

/* @ngInject */
function validatorLastname() {

    var directive = {
        require: 'ngModel',
        link: link
    };

    return directive;

    function link(scope, element, attrs, modelCtrl) {

        var valid = false;

        var formatter = function (inputValue) {
            if (inputValue) {
                var res = inputValue.match(/^[\'a-zA-Z_]+( [\'a-zA-Z_]+)*$/);
                if (res && res.length > 0) {
                    valid = true;
                }

                modelCtrl.$setValidity('pattern', valid);
                valid = false;
            }else{
                modelCtrl.$setValidity('pattern', true);  
            }
            return inputValue;
        };
        modelCtrl.$parsers.push(formatter);
        if (scope[attrs.ngModel] && scope[attrs.ngModel] !== '') {
            formatter(scope[attrs.ngModel]);
        }
    }
}

I have created a plunk for your problem... It is because if inputValue is null then your $setValidity method will not invoke and could not perform validation again. You should set pattern validity to true inside else part. if you want to make field valid for no-input. You can now refer to updated plunk https://plnkr.co/edit/N3DrsB?p=preview

查看更多
登录 后发表回答