自定义验证指令会覆盖其他验证

时间:2014-06-19 03:48:43

标签: javascript angularjs validation

我创建了一个自定义验证,用于验证用户是否存在。如果用户不存在,则必须验证此验证。这是一个返回JSON内容的简单GET查询。

问题在于此验证似乎会覆盖其他验证。如果用户不存在但是少于3个字符,通常不应该验证该字段,但它是!如果我删除了我创建的自定义验证,问题就会消失,长度验证也会起作用。

这是我的代码:

angular.module('userRegistrationApp').directive('usernameNotExist', function($http) {
    return {
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl) {
            ctrl.$parsers.unshift(function(viewValue){
                var user = viewValue;

                $http({method: 'GET', url: '/register/doesUserOrEmailExist/' + user }).
                    success(function(data, status, headers, config) {

                       if(data.doesUserOrEmailExist == false) {
                            ctrl.$setValidity('usernameNotExist', true);
                            return viewValue;
                        }else {
                            ctrl.$setValidity('usernameNotExist', false);
                            return undefined
                        }
                    }).error(function(data, status, headers, config) {
                        ctrl.$setValidity('usernameNotExist', false);
                        return undefined;
                    })

            });
        }
    }
});

<input type="text" id="sonata_user_registration_form_username" name="sonata_user_registration_form[username]" required="required" maxlength="255" pattern=".{2,}" class="form-control" username-not-exist="" ng-minlength="3" ng-focus="setFocus('username')" ng-model="userRegistrationService.username">

我完全遵循他们在文档中所说的内容,但我收到了这个错误!

2 个答案:

答案 0 :(得分:1)

我想我找到了解决方案。它的灵感来自这个答案:https://stackoverflow.com/a/12865401/2573319

尝试以下指令,看看它是否适合你!

angular.module('userRegistrationApp').directive('usernameNotExist', function($http) {
    var timeout;
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl) {
                scope.$watch(attrs.ngModel, function(value) {
                    var user = value;
                    // if there was a previous attempt, stop it.
                    if(timeout)
                        clearTimeout(timeout);

                    // start a new attempt with a delay to keep it from
                    // getting too "chatty".
                    timeout = setTimeout(function(){
                        // call to some API that returns { isValid: true } or { isValid: false }
                        $http({method: 'GET', url: '/register/doesUserOrEmailExist/' + user }).success(function(data) {
                            if(data.doesUserOrEmailExist == false) {
                                ctrl.$setValidity('usernameNotExist', true);
                            }
                            else {
                                ctrl.$setValidity('usernameNotExist', false);
                            }
                        }).error(function(data) {
                            ctrl.$setValidity('usernameNotExist', false);
                        });
                    }, 200);
                })

        }
    }
});

答案 1 :(得分:1)

我遇到了同样的问题,发现解决方案是使用

  

scope.$watch

而不是

  

ctrl.$parsers.unshift

在我看来,ctrl.$parsers.unshift将在其他验证之前执行自定义验证,然后如果您的自定义验证失败,return undefined;会将模型值设置为undefined,以便其他验证不会要处理的有效值。

在所有其他验证通过后,

scope.$watch将触发您的自定义验证。

我还没有找到任何支持角度文档的东西,这是基于我的调试经验。