javascript - 使用 AngularJS ngModel 和表单验证 $watch 两个元素并在任一输入更改时测试它们是否相等

标签 javascript angularjs angularjs-directive watch angularjs-ng-model

我想要做的是创建一个指令来比较两个密码输入并在其中任何一个发生更改时触发无效。我找到了一些例子,尝试了一些,并在我自己的尝试中结合了一些。但是,当确认密码字段更改时,我只能使用 $setValidity 切换有效性。当您更改密码字段时,不会触发比较无效。

这是我的指令:

app.directive("passwordVerify", function() {
    return {
        require: "ngModel",
        scope: {
            passwordVerify: '=',
        },
        link: function(scope, element, attrs, ctrl) {
            scope.$watch(function() {
                var combined;

                if (scope.passwordVerify || ctrl.$viewValue) {
                    combined = scope.passwordVerify + '_' + scope.$view; 
                }                    
                return combined;
            }, function(value) {
                if (value) {
                    ctrl.$parsers.unshift(function(viewValue) {
                        var origin = scope.passwordVerify;
                        if (origin !== viewValue) {
                            ctrl.$setValidity("pwd", false);
                            return undefined;
                        } else {
                            ctrl.$setValidity("pwd", true);
                            return viewValue;
                        }
                    });
                }
            });
        }
    };
});

这是正在执行的指令:

<input id="user_password" type="password" name='user_password' placeholder="password" value='' required ng-model="user.user_password">
<p class="help-text">Required</p>
<div class="help-block" ng-messages="add_user_form.user_password.$error" ng-show="add_user_form.user_password.$touched">
<div ng-messages-include="/app/views/messages.html" ></div>

<input id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" name="user_confirm_password" required password-verify="user.user_password">
<p class="help-text">Enter matching password</p>
<div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-show="add_user_form.confirm_password.$touched">
<div ng-messages-include="/app/views/messages.html" ></div>

使用此代码,当我更改确认密码字段的值时,我可以验证密码是否匹配,但是当您更改密码字段的值时,它不会重新验证输入。我非常确定有一种成功的方法可以将 $watch 添加到两个元素或使用 $watchgroup 来执行此操作。我就是想不通。我知道关于这个主题有很多问题,但我所做的一切仅让我达到这一点。

顺便说一句,我正在使用 Angular 1.5.7...

最佳答案

这是一个双向工作的版本:

(function() {
  "use strict";
  angular.module('app', ['ngMessages'])
    .controller('mainCtrl', function($scope) {

    })

  .directive('passwordVerify', function() {
    return {
      restrict: 'A', // only activate on element attribute
      require: '?ngModel', // get a hold of NgModelController
      link: function(scope, elem, attrs, ngModel) {
        if (!ngModel) return; // do nothing if no ng-model

        // watch own value and re-validate on change
        scope.$watch(attrs.ngModel, function() {
          validate();
        });

        // observe the other value and re-validate on change
        attrs.$observe('passwordVerify', function(val) {
          validate();
        });

        var validate = function() {
          // values
          var val1 = ngModel.$viewValue;
          var val2 = attrs.passwordVerify;

          // set validity
          ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2);
        };
      }
    }
  })
})();
<html ng-app="app">

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.7/angular-messages.min.js"></script>
</head>

<body ng-controller="mainCtrl">
  <form name="add_user_form">
    <div class="col-md-12">
      <div class="form-group" ng-class="{ 'has-error' : add_user_form.user_password.$touched && add_user_form.user_password.$invalid }">
        <p class="help-text">Enter password</p>
        <input type="password" class="form-control" id="user_password" name="user_password" placeholder="password" required ng-model="user.user_password" password-verify="{{user.confirm_password}}">
        <div class="help-block" ng-messages="add_user_form.user_password.$error" ng-show="add_user_form.user_password.$touched">
          <p ng-message="required">This field is required</p>
          <p ng-message="minlength">This field is too short</p>
          <p ng-message="maxlength">This field is too long</p>
          <p ng-message="required">This field is required</p>
        </div>
      </div>
      <div class="form-group" ng-class="{ 'has-error' : add_user_form.confirm_password.$touched && add_user_form.confirm_password.$invalid }">
        <p class="help-text">Enter matching password</p>
        <input class="form-control" id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" required password-verify="{{user.user_password}}">
        <div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-show="add_user_form.confirm_password.$touched">
          <p ng-message="required">This field is required</p>
          <p ng-message="minlength">This field is too short</p>
          <p ng-message="maxlength">This field is too long</p>
          <p ng-message="required">This field is required</p>
          <p ng-message="passwordVerify">No match!</p>
        </div>
      </div>
    </div>
  </form>
</body>

</html>

希望对您有所帮助。

关于javascript - 使用 AngularJS ngModel 和表单验证 $watch 两个元素并在任一输入更改时测试它们是否相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38406212/

相关文章:

javascript - 该指令从不重新加载其内容

javascript - 使用 angularjs 指令操作范围值

javascript - 使用 ng-model 将数组中的选择列表发布到服务器

angularjs 指令的 '$element' 是一个注释,因为 ng-if

javascript - 谷歌查看器经常打开空白页

Javascript 子字符串无法提取正确的数据

javascript - 将 HTML 标签设置为对象的值

javascript - 很难调试错误 - 第 2 列的 token '{' 无效 key

java - 如何在 JSP 中单击一个按钮来提交来自 for 循环的多个表单

javascript - Coffeescript 未捕获类型错误 : object is not a function Error