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

Using AngularJS ngModel and Form Validation to $watch two elements and test if they are equal whenever either input changes

本文关键字:输入 任一 测试 是否 元素 验证 表单 AngularJS ngModel watch 两个      更新时间:2023-09-26

我正在尝试做的是创建一个指令,该指令比较两个密码输入,并在任一更改时触发器无效。我找到了一些例子,也尝试了几个,并在我自己的尝试中结合了一些。但是,我只能在确认密码字段更改时$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来执行此操作。我只是想不通。我知道关于这个话题有很多问题,但我所尝试的一切只是让我走到了这一步。

顺便说一句,我正在使用角度 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>

我希望它有所帮助。