3

我正在尝试编写自己的一组指令。我写了以下两个指令:

  • eaValidateEmail(验证电子邮件地址的格式)
  • eaValidateUnique(完成后将通过调用休息服务来验证唯一性)

我想要达到的目标:

  • 首先执行 eaValidateEmail 指令,该指令返回 false,直到电子邮件的格式正确
  • 然后,只有这样 eaValidateUnique 指令才应该执行并检查电子邮件地址是否已经被其他服务接管。如果未找到该值,则返回 true,否则返回 false。

发生了什么

当我只添加 eaValidateEmail 指令时,一切正常并且电子邮件的格式得到验证。

但是,一旦我添加了 eaValidateUnique 指令,那么 eaValidateEmail 指令就被忽略了,并且 eaValidateUnique 指令的 ctrl.$valid 方法总是通过,即使在 console.log 中 ctrl.$valid 为 false。

我已经阅读了 AngularJS 文档,买了两本书,但这些示例总是非常基础的。目前我无法弄清楚问题可能出在哪里。看起来与 ngModelController 存在冲突,但我无法找到解决此问题的正确方法。

我目前正在使用 ValidateCtrlNew 表单进行测试。因此,html 表单的“新建”部分中的字段。

问题:

  • 有人知道如何编写指令,以便在我将它们作为属性添加到输入元素时按顺序执行它们吗?
  • 如何防止与指令发生此类冲突?隔离范围也不是多个指令的选项。

这是jsfiddle:http: //jsfiddle.net/charms/6j3U8/230/

<div ng-controller="ValidateCtrlNew">
    <form name="user_form_new" class="pure-form" novalidate>
        <fieldset>    
            <legend>New</legend>
            <input type="text" name="email" ng-model="user.email" placeholder="E-Mail" class="txt_fld" ng-required="true"  ea-validate-email ea-validate-unique/><br/>
            <div class="inv_msg" ng-show="user_form_new.email.$dirty && user_form_new.email.$invalid">Invalid:
                <span ng-show="user_form_new.email.$error.required">Please enter your email.</span>
                <span ng-show="user_form_new.email.$error.eaValidateEmail">This is not a valid email.</span>
                <span ng-show="user_form_new.email.$error.eaValidateEmailCheck">Checking email....</span>
                <span ng-show="user_form_new.email.$error.eaValidateUnique">This email is already taken.</span>
            </div>                
        </fieldset>
    </form>
</div>


.directive('eaValidateUnique', ['$http', function($http) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elem, attr, ctrl) {
            ctrl.$parsers.push(function(viewValue) {
                console.log(ctrl);
                //ctrl.$setValidity('eaValidateUnique', true);
                if(ctrl.$valid) {
                    ctrl.$setValidity('eaValidateUnique', false);
                    console.log("valid was true");
                }                    
            });
        }
    };
}])
.directive('eaValidateEmail', [function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elem, attr, ctrl) {
            var EMAIL_REGEXP = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
            ctrl.$parsers.push(function(viewValue) {
                // set validity to true to clear out if previous validators fail
                ctrl.$setValidity('eaValidateEmail', true);
                if(ctrl.$valid) {
                    // set validity to false as we need to check the value here
                    ctrl.$setValidity('eaValidateEmail', false);
                    if(viewValue !== undefined && viewValue !== "" && EMAIL_REGEXP.test(viewValue)) {
                        // if the format of the email is valid then we set validity to true
                        ctrl.$setValidity('eaValidateEmail', true);
                        ctrl.$setValidity('eaValidateEmailCheck', true);
                        console.log("TRUE");
                    } else {
                        // if the format of the email is invalid we set validity to false
                        ctrl.$setValidity('eaValidateEmail', false);
                        ctrl.$setValidity('eaValidateEmailCheck', true);
                        console.log("FALSE");
                    }    
                }
                return viewValue;
            });
        }
    };
}]);
4

2 回答 2

2

您可以将 eaValidateEmail 的优先级添加到 100,例如..

restrict: 'A',
 priority:'100',
    require: 'ngModel',
于 2014-12-11T11:06:47.757 回答
0

据我了解,验证器链接在 $parsers 数组上。如果验证器确定该值是否有效,则 AngularJs 验证器返回该值,但如果该值无效则返回未定义。

这样,您链上的其他验证器将不再具有可使用的价值。

http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController# $parsers

于 2013-12-04T15:24:23.553 回答