javascript - AngularJS - 验证元素绑定(bind)上的可用电子邮件

标签 javascript angularjs validation bind directive

我在“电子邮件”输入字段上使用“必需”和“电子邮件”验证器。验证器使用解析器和格式化器,并且它们工作得很好。不过,我也对“绑定(bind)”事件进行了一些验证。

这是指令:

angular.module('simpleRepairApp')
  .directive('uniqueEmail', function (Checker) {
    return {
      require:'ngModel',
      restrict:'A',
      link:function ($scope, element, attrs, model) {    
        var last = '';
        var current = '';    
        element.bind('blur', function() {    
          current = element.val();    
          console.log(current, last);    
          if(current !== last){
            Checker.email({ email:current }).then(
              function(response) {
                model.$setValidity('uniqueEmail', response.available);
              }
            );
          }    
          last = current;    
        });    
      }
  };
});

我需要在用户点击字段后检查电子邮件是否已存在于数据库中(我不想检查每次按键或更改)。

我遇到的问题是,执行唯一验证后,它会显示唯一的错误消息,但在您键入更正电子邮件后,模型值保持未定义状态。您必须单击输入,然后再次定义模型中的值。

任何人都可以帮我解决这个问题,这让我发疯!:)

工作解决方案:

angular.module('simpleRepairApp')
  .directive('emailUnique', function () {
    return {
      restrict: 'E',
      require: ['form', 'ngModel'],
      scope: {
        'form': '=form',
        'model': '=ngModel',
        'labelClass': '@',
        'inputClass': '@'
      },
      compile: function(element, attrs)
      {
        if (!attrs.labelClass) { attrs.labelClass = 'col-sm-4'; }
        if (!attrs.inputClass) { attrs.inputClass = 'col-sm-8'; }
        attrs.required = attrs.required == 'true';
      },
      controller: function($scope, Checker) {

        $scope.checkEmail = function() {

          var email = $scope.form.email.$viewValue;
          var checkField = $scope.form.emailCheck;

          Checker.email({ email:email }).then(
            function(response) {
              checkField.$setValidity('unique', response.available);
              $scope.form.$setValidity('check', true);
              checkField.hasVisit = true;
            }
          );

        };

        $scope.setUnchecked = function() {
          console.log($scope.form);
          $scope.form.emailCheck.hasVisited = false;
          $scope.form.$setValidity('check', false);
          $scope.form.emailCheck.$setValidity('unique', true);

        };

      },
      template: '<div ng-class="{ \'has-error\' : !form.email.$valid || !form.emailCheck.$valid }">' +
                  '<label class="{{ labelClass }} control-label required" for="email" translate>E-mail</label>' +
                  '<div class="{{ inputClass }}">' +
                    '<input name="email" class="form-control" type="email" id="email" ng-model="model" ng-change="setUnchecked()" ng-blur="checkEmail()" ng-required="true" autocomplete="off">' +
                    '<div class="help-block" ng-show="(!form.email.$valid || !form.emailCheck.$valid) && !form.email.$pristine">' +
                      '<div ng-messages="form.email.$error">' +
                        '<div ng-message="required"><span translate>Please enter your e-mail.</span></div>' +
                        '<div ng-message="email"><span translate>Please enter a valid e-mail.</span></div>' +
                      '</div> ' +
                      '<div ng-messages="form.emailCheck.$error">' +
                        '<div ng-message="check"><span translate>E-mail will be checked upon blur.</span></div>' +
                        '<div ng-message="unique"><span translate>This e-mail is already in use.</span></div>' +
                      '</div> ' +
                    '</div>' +
                    '<input name="emailCheck" type="hidden" class="form-control" ng-model="checked">' +
                    '<div class="help-block" ng-messages="form.emailCheck.$error" ng-show="!form.emailCheck.$valid">' +
                    '</div>' +
                  '</div>' +
                '</div>'
    };
  });

最佳答案

我认为您可能会通过制定指令使事情变得复杂一些,为什么不简单地向 Controller 添加一个观察者呢?

注意:我不知道这些方法是否适合您,但我添加它们是为了说明目的,即不绑定(bind)到“模糊”事件,而是触发事件当模型改变时。这就是 Angular 的设计目的。我还假设您的检查器正在正确处理 promise

第一种替代方法(使用 $watch)

<form name="myForm" ng-controller="ExampleController">
    <input type="email" name="input" ng-model="text" required />
</form>

然后在你的 ng-app Controller 中:

function isNullOrUndefined(value) {
    return (value == 'undefined' || value == null);
}

//listener on the ng-model='text', waiting for the data to get dirty
$scope.$watch('text', function (newValue, oldValue) {
   if (newValue != oldValue)
   {
       var truthyVal = !(isNullOrUndefined(newValue));
       if (truthyVal) {
           //angular's way of checking validity as well
           //$scope.myForm.text.$valid
           Checker.email({ email:current }).then(
           function(response) {
              model.$setValidity('textErr', response.available);
          }
       }
   }
}, true);

第二种替代方法(使用 ng-change):

<form name="myForm" ng-controller="ExampleController">
    <input type="email" name="input" ng-model="text" ng-change="checkEmail()" required />
</form>

$scope.checkEmail = function(){
    Checker.email({ email:current }).then(
       function(response) {
          model.$setValidity('textErr', response.available);
       }
}

关于javascript - AngularJS - 验证元素绑定(bind)上的可用电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25127088/

相关文章:

javascript - 避免强制回调

javascript - Angularjs 没有可视化输入选择中的第一个选项

javascript - 如何使用 dom id 将普通 JavaScript keyup 监听器附加到 Angular md-autocomplete 输入?

javascript - 谷歌图表未正确显示图例

javascript - 输入不会更新 javascript

javascript - 动态禁用 jqGrid 行

javascript - scrollTop 函数的 jQuery 延迟

javascript - 将 .ready 和 .resize 链接到函数中?

spring - 如何在 freemarker 模板中显示验证错误

validation - 使用 Yup 检查数组是否包含字符串