【问题标题】:password-check directive in angularjsangularjs中的密码检查指令
【发布时间】:2012-12-23 15:34:49
【问题描述】:

我正在编写密码验证指令:

 Directives.directive("passwordVerify",function(){
    return {
        require:"ngModel",
        link: function(scope,element,attrs,ctrl){
            ctrl.$parsers.unshift(function(viewValue){
                var origin = scope.$eval(attrs["passwordVerify"]);
                if(origin!==viewValue){
                    ctrl.$setValidity("passwordVerify",false);
                    return undefined;
                }else{
                    ctrl.$setValidity("passwordVerify",true);
                    return viewValue;
                }
            });

        }
    };
});

html:

<input data-ng-model='user.password' type="password" name='password' placeholder='password' required>
<input data-ng-model='user.password_verify' type="password" name='confirm_password' placeholder='confirm password' required data-password-verify="user.password">

给定表单中的 2 个密码字段,如果两个密码值相等,则受指令影响的字段有效。 问题是它以一种方式工作(即当我在密码验证字段中输入密码时)。但是,当原始密码字段更新时,密码验证无效。

知道如何进行“双向绑定验证”吗?

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    我使用以下指令是因为我想重新验证两个输入字段,而不管值 1 或值 2 是否已更改:

    指令:

    'use strict';
    
    angular.module('myApp').directive('equals', 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('equals', function (val) {
            validate();
          });
    
          var validate = function() {
            // values
            var val1 = ngModel.$viewValue;
            var val2 = attrs.equals;
    
            // set validity
            ngModel.$setValidity('equals', ! val1 || ! val2 || val1 === val2);
          };
        }
      }
    });
    

    用法

    <input type="password" ng-model="value1" equals="{{value2}}" required>
    <input type="password" ng-model="value2" equals="{{value1}}" required>
    

    【讨论】:

    • 我发现这很好用。让我措手不及的一件事是,如果您在第一个字段上有一些其他角度验证器,例如:ng-minlength,那么该模型在实际有效之前不会设置
    • 我用if (val1 &amp;&amp; val2) { .. } 包裹了ngModel.$setValidity,这样当两个值都为空时表单不会无效。
    • 当有更多的验证规则在起作用时,这会出现一些小问题。如果另一个验证失败,Angular 不会更新模型并且在比较中会发生奇怪的事情......
    • 这对我很有用。作为新手,将验证字符串添加到此会有所帮助。 [form name].[field name].$error.equals 使用它来控制应该或应该显示哪些字段。我将它用于错误标签。
    • 我觉得把ngModel.$setValidity('equals', val1 === val2);换成ngModel.$setValidity('equals', ! val1 || ! val2 || val1 === val2);比较好
    【解决方案2】:

    不需要为此创建单独的指令。已经有一个build in Angular UI password validation tool。有了这个你可以这样做:

    <input name="password" required ng-model="password">
    <input name="confirm_password"
           ui-validate=" '$value==password' "
           ui-validate-watch=" 'password' ">
    
     Passwords match? {{!!form.confirm_password.$error.validator}}
    

    【讨论】:

    • 目前需要 jQuery
    • @DominicWatson 你反对我的理由是什么?这个问题是关于角度的,我指的是角度文档。如果你不明白它们之间的区别,那就去学习吧。
    • @DominicWatson 指令在这里github.com/angular-ui/ui-utils/blob/master/modules/validate/…,除了jquery lite,里面没有可怕的jquery。如果你这么反 jquery,你不应该使用这个框架,因为它包含 jquery。
    • 我遇到了与原始帖子相同的问题。如果 angular-ui 已经内置了一些东西,那么使用它而不是重新发明轮子是否有意义?
    • @PeterG 我认为 Dominic Watson 不知道他在说什么
    【解决方案3】:

    这应该解决它:

    查看:

    <div ng-controller='Ctrl'>
       <form name='form'>
          <input data-ng-model='user.password' type="password" name='password' placeholder='password' required>
          <div ng-show="form.password.$error.required">
            Field required</div>
          <input ng-model='user.password_verify' type="password" name='confirm_password' placeholder='confirm password' required data-password-verify="user.password">
          <div ng-show="form.confirm_password.$error.required">
            Field required!</div>
          <div ng-show="form.confirm_password.$error.passwordVerify">
            Fields are not equal!</div>
       </form
    </div>
    

    指令

    var app = angular.module('myApp', []);
    
    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 + '_' + ctrl.$viewValue; 
                }                    
                return combined;
            }, function(value) {
                if (value) {
                    ctrl.$parsers.unshift(function(viewValue) {
                        var origin = scope.passwordVerify;
                        if (origin !== viewValue) {
                            ctrl.$setValidity("passwordVerify", false);
                            return undefined;
                        } else {
                            ctrl.$setValidity("passwordVerify", true);
                            return viewValue;
                        }
                    });
                }
            });
         }
       };
    });
    

    【讨论】:

    • 我在文档中使用了验证sn-p,让我试试你的代码。
    • 我改变了我的答案。这应该有效。见jsFiddle
    • 我同意 CWSpear。解决方案应该用上面评论的错误来纠正
    • 此解决方案存在内存泄漏。通过将另一个解析器推送到 ctrl.$parsers 数组中触发的每个监视事件。在 watch 事件处理程序末尾检查 ctrl.$parsers.length 将显示此内容。
    • 这个方案有一个重大缺陷:如果用户输入正确的2个密码,然后更改第一个密码(即user.password模型),不会触发错误。
    【解决方案4】:

    对此的另一种看法是将一个输入的模型与另一个输入的值相匹配。

    app.directive('nxEqual', function() {
        return {
            require: 'ngModel',
            link: function (scope, elem, attrs, model) {
                if (!attrs.nxEqual) {
                    console.error('nxEqual expects a model as an argument!');
                    return;
                }
                scope.$watch(attrs.nxEqual, function (value) {
                    model.$setValidity('nxEqual', value === model.$viewValue);
                });
                model.$parsers.push(function (value) {
                    var isValid = value === scope.$eval(attrs.nxEqual);
                    model.$setValidity('nxEqual', isValid);
                    return isValid ? value : undefined;
                });
            }
        };
    });
    

    所以,如果密码框的型号是login.password,那么你在验证框上设置如下属性:nx-equal="login.password",并测试formName.elemName.$error.nxEqual。像这样:

    <form name="form">
        <input type="password" ng-model="login.password">
        <input type="password" ng-model="login.verify" nx-equal="login.password" name="verify">
        <span ng-show="form.verify.$error.nxEqual">Must be equal!</span>
    </form>
    

    扩展版:

    对于我的一个新项目,我必须修改上述指令,使其仅在且仅当验证输入具有值时才显示nxEqual 错误。否则 nxEqual 错误应该被忽略。这是扩展版:

    app.directive('nxEqualEx', function() {
        return {
            require: 'ngModel',
            link: function (scope, elem, attrs, model) {
                if (!attrs.nxEqualEx) {
                    console.error('nxEqualEx expects a model as an argument!');
                    return;
                }
                scope.$watch(attrs.nxEqualEx, function (value) {
                    // Only compare values if the second ctrl has a value.
                    if (model.$viewValue !== undefined && model.$viewValue !== '') {
                        model.$setValidity('nxEqualEx', value === model.$viewValue);
                    }
                });
                model.$parsers.push(function (value) {
                    // Mute the nxEqual error if the second ctrl is empty.
                    if (value === undefined || value === '') {
                        model.$setValidity('nxEqualEx', true);
                        return value;
                    }
                    var isValid = value === scope.$eval(attrs.nxEqualEx);
                    model.$setValidity('nxEqualEx', isValid);
                    return isValid ? value : undefined;
                });
            }
        };
    });
    

    你会像这样使用它:

    <form name="form">
        <input type="password" ng-model="login.password">
        <input type="password" ng-model="login.verify" nx-equal-ex="login.password" name="verify">
        <span ng-show="form.verify.$error.nxEqualEx">Must be equal!</span>
    </form>
    

    试试看:http://jsfiddle.net/gUSZS/

    【讨论】:

    • 这个是最好的。这是最简洁的。它适用于模型值,并且可以双向工作。
    • 不过,有一件事是 $parser 管道应该返回值或未定义。这样后续管道就不会结束,因为当没有返回函数时,它总是返回 undefined 。范围也应该是假的。
    • @CMCDragonkai: 好收获!我已经更新了解析器函数的返回值。关于范围,据我所知,它默认为false,因此通过不明确指定范围,它等于scope: false
    • 我认为它实际上默认为 true 作为子范围。不过最近没查过。
    • @GillBates 使用隔离范围并通过= 绑定参数将不会在第一个输入被填写后重新检查。我做了一个快速的JSFiddle 来显示这个问题。
    【解决方案5】:

    我在没有指令的情况下完成了它。

    <input type="password" ng-model="user.password" name="uPassword" required placeholder='Password' ng-minlength="3" ng-maxlength="15" title="3 to 15 characters" />
        <span class="error" ng-show="form.uPassword.$dirty && form.uPassword.$error.minlength">Too short</span>
        <span ng-show="form.uPassword.$dirty && form.uPassword.$error.required">Password required.</span><br />
    
        <input type="password" ng-model="user.confirmpassword" name="ucPassword" required placeholder='Confirm Password' ng-minlength="3" ng-maxlength="15" title="3 to 15 characters" />
        <span class="error" ng-show="form.ucPassword.$dirty && form.ucPassword.$error.minlength">Too short</span>
        <span ng-show="form.ucPassword.$dirty && form.ucPassword.$error.required">Retype password.</span>
        <div ng-show="(form.uPassword.$dirty && form.ucPassword.$dirty) && (user.password != user.confirmpassword)">
            <span>Password mismatched</span>
        </div>
    

    【讨论】:

    • 您应该使用已经指出的指令,表单保持有效状态。否则你也可以为它制作一些 jquery 监听器。
    【解决方案6】:

    https://github.com/wongatech/angular-confirm-field 是一个很好的项目。

    这里的例子http://wongatech.github.io/angular-confirm-field/

    下面的代码显示了 2 个具有已实现功能的输入字段

    <input ng-confirm-field ng-model="emailconfirm" confirm-against="email" name="my-email-confirm"/>
    <input ng-model="email" name="my-email" />
    

    【讨论】:

      【解决方案7】:

      从 Angular 1.3.0-beta12 开始,无效输入不会写入 ngModel,因此您无法观看并验证,如您在此处看到的:http://plnkr.co/edit/W6AFHF308nyKVMQ9vomw?p=preview。引入了新的验证器管道,您可以附加到此管道以实现相同的目的。

      实际上,在那张纸条上,我为常见的额外验证器创建了一个凉亭组件:https://github.com/intellix/angular-validators,其中包括这个。

      angular.module('validators').directive('equals', function() {
          return {
              restrict: 'A',
              require: '?ngModel',
              link: function(scope, elem, attrs, ngModel)
              {
                  if (!ngModel) return;
      
                  attrs.$observe('equals', function() {
                      ngModel.$validate();
                  });
      
                  ngModel.$validators.equals = function(value) {
                      return value === attrs.equals;
                  };
              }
          };
      });
      
      angular.module('validators').directive('notEquals', function() {
          return {
              restrict: 'A',
              require: '?ngModel',
              link: function(scope, elem, attrs, ngModel)
              {
                  if (!ngModel) return;
      
                  attrs.$observe('notEquals', function() {
                      ngModel.$validate();
                  });
      
                  ngModel.$validators.notEquals = function(value) {
                      return value === attrs.notEquals;
                  };
              }
          };
      });
      

      【讨论】:

      • 我猜迄今为止最好的解决方案
      【解决方案8】:

      我之前成功使用过这个指令:

       .directive('sameAs', function() {
        return {
          require: 'ngModel',
          link: function(scope, elm, attrs, ctrl) {
            ctrl.$parsers.unshift(function(viewValue) {
              if (viewValue === scope[attrs.sameAs]) {
                ctrl.$setValidity('sameAs', true);
                return viewValue;
              } else {
                ctrl.$setValidity('sameAs', false);
                return undefined;
              }
            });
          }
        };
      });
      

      用法

           <input ... name="password" />
          <input type="password" placeholder="Confirm Password" 
      name="password2" ng-model="password2" ng-minlength="9" same-as='password' required>
      

      【讨论】:

      • 我最喜欢这个解决方案——不限制密码匹配
      【解决方案9】:

      我正在处理同样的问题,并找到了一个很好的 blog post 由 Piotr Buda 撰写的。这是一本很好的读物,它很好地解释了这个过程。代码如下:

      directives.directive("repeatPassword", function() {
          return {
              require: "ngModel",
              link: function(scope, elem, attrs, ctrl) {
                  var otherInput = elem.inheritedData("$formController")[attrs.repeatPassword];
      
                  ctrl.$parsers.push(function(value) {
                      if(value === otherInput.$viewValue) {
                          ctrl.$setValidity("repeat", true);
                          return value;
                      }
                      ctrl.$setValidity("repeat", false);
                  });
      
                  otherInput.$parsers.push(function(value) {
                      ctrl.$setValidity("repeat", value === ctrl.$viewValue);
                      return value;
                  });
              }
          };
      });
      

      所以你可以这样做:

      <input type="password" name="repeatPassword" id="repeatPassword" placeholder="repeat password" ng-model="user.repeatPassword" repeat-password="password" required>
      

      感谢作者

      【讨论】:

      • 经过一番折腾后,这对我来说也是使用其他验证属性(例如最小长度、要求等)时的最佳解决方案
      【解决方案10】:

      这还不够好吗:

      <input type="password" ng-model="passwd1" />
      <input type="password" ng-model="passwd2" />
      <label ng-show="passwd1 != passwd2">Passwords do not match...</label>
      <button ng-disabled="passwd1 != passwd2">Save</button>
      

      简单,适合我。

      【讨论】:

      • 这不是验证。 form.$valid 将等于 true。
      • 我们可以禁用保存按钮,直到满足密码条件(添加同上)。
      • 这仍然不是正确的验证。有一个完整的验证系统,不使用它来节省几行只是愚蠢的。
      • Dennis Kr0ger> 它工作正常.. 你能指出它有什么问题吗?
      【解决方案11】:

      这个解决方案类似于 Dominic Watson 给出的解决方案,它使用 $validators 并且是我最喜欢的解决方案。唯一的变化是您可以观看表达式。

      $validators 验证器的集合,每当 模型值变化。对象内的键值是指 验证器的名称,而函数引用验证 手术。验证操作提供模型值 作为参数,并且必须返回真或假值,具体取决于 该验证的响应

      来自https://code.angularjs.org/1.3.15/docs/api/ng/type/ngModel.NgModelController

      我正在使用 Angular 1.3。我的指令看起来像这样

      angular.module('app').directive("passwordConfirm", function() {
          "use strict";
          return {
              require : "ngModel",
              restrict : "A",
              scope : {
                  //We will be checking that our input is equals to this expression
                  passwordConfirm : '&'
              },
              link : function(scope, element, attrs, ctrl) {
                  //The actual validation
                  function passwordConfirmValidator(modelValue, viewValue) {
                      return modelValue == scope.passwordConfirm();
                  }
                  //Register the validaton when this input changes
                  ctrl.$validators.passwordConfirm = passwordConfirmValidator;
                  //Also validate when the expression changes
                  scope.$watch(scope.passwordConfirm, ctrl.$validate);
              }
          };
      });
      

      使用它

      <input type="password" ng-model="user.password"/>
      <input type="password" ng-model="user.confirmPassword" 
                      password-confirm="user.password" />
      

      【讨论】:

        【解决方案12】:

        为了验证带有两个输入字段的表单,我找到了最合适的方式

        指令

        app.directive('passwordVerify', function() {
        return {
            require: 'ngModel',
            link: function (scope, elem, attrs, ctrl) {
                if (!attrs.passwordVerify) {
                    return;
                }
                scope.$watch(attrs.passwordVerify, function (value) {
                  if( value === ctrl.$viewValue && value !== undefined) {
                     ctrl.$setValidity('passwordVerify', true);
                     ctrl.$setValidity("parse",undefined);
                  }
                  else {
                     ctrl.$setValidity('passwordVerify', false);
                  }
                });
                ctrl.$parsers.push(function (value) {
                    var isValid = value === scope.$eval(attrs.passwordVerify);
                    ctrl.$setValidity('passwordVerify', isValid);
                    return isValid ? value : undefined;
                });
            }
          };
        });
        

        HTML

             <div class="row">
                <div class="col-md-10 col-md-offset-1">
                  <div class="form-group" ng-class="{ 'has-error': form.password.$dirty && form.password.$error.required || (form.password.$error.minlength || form.password.$error.maxlength)}">
                      <input type="password" name="password" ng-minlength="6" ng-maxlength="16" id="password" class="form-control" placeholder="Password" ng-model="user.password" required />
                      <span ng-show="form.password.$dirty && form.password.$error.required" class="help-block">Password is required</span>
                      <span ng-show="form.password.$error.minlength || form.password.$error.maxlength" class="help-block">Password must be 6-16 character long</span>
                  </div>
                </div>
               </div>
               <div class="row">
                 <div class="col-md-10 col-md-offset-1">
                   <div class="form-group" ng-class="{ 'has-error': (form.confirm_password.$dirty && form.confirm_password.$error.required) || form.confirm_password.$error.passwordVerify }">
                      <input type="password" name="confirm_password" id="confirm_password" class="form-control" placeholder="Confirm Password" ng-model="user.confirm_password" required password-verify="user.password" />
                      <span ng-show="form.confirm_password.$dirty && form.confirm_password.$error.required" class="help-block">Confirm Password is required</span>
                      <span ng-show="form.confirm_password.$error.passwordVerify" class="help-block">Please make sure passwords match & must be 6-16 character long</span>
                  </div>
                </div>
              </div>
        

        【讨论】:

          【解决方案13】:

          这两种方式都适用,而且简单干净

          JavaScript

          var app = angular.module("app");
          
          app.controller("SamePaswordController", function () {
          
            this.password;
            this.confirm;
          
            this.save = function () {
              alert("Saved!");
            };
          }
          
          
          app.directive("match", function () {
            return {
              restrict:"A",
              require:"ngModel",
          
              link: function(scope, element, attrs, ctrl) {
          
                function matchValidator(value) {      
          
                  scope.$watch(attrs.match, function(newValue, oldValue) {
          
                    var isValid = value === scope.$eval(attrs.match);                    
                    ctrl.$setValidity('match', isValid);
          
                  });
          
                  return value;
                }
          
                ctrl.$parsers.push(matchValidator);
              }
            };
          });
          

          HTML:注意匹配指令

          <form name="regForm" ng-controller="SamePaswordController as regCtrl"
                ng-submit="regForm.$valid && regCtrl.save()" novalidate>
          
            <input name="password" ng-model="regCtrl.password" 
                   type="password" required placeholder="Password"/>                
          
            <input name="confirm" ng-model="regCtrl.confirm" match="regCtrl.password"
                   type="password" required placeholder="Confirm password"/>
          
          
            <div> regForm is valid:{{regForm.$valid}}</div>
          
            <input type="submit" value="Save"/>
          
          </form>
          

          您可以使用此示例克隆 repo https://github.com/rogithub/roangularjs

          【讨论】:

          • 不错的部分是:scope.$watch、scope.$eval 和 match="regCtrl.password"。
          • 这对我不起作用。观看确认更改以及我认为不正确的示例。匹配={{ regCtrl.password" }}
          【解决方案14】:

          不是指令解决方案,但对我有用:

          <input ng-model='user.password'
           type="password"
           name='password'
           placeholder='password'
           required>
          <input ng-model='user.password_verify'
           type="password" 
           name='confirm_password'
           placeholder='confirm password'
           ng-pattern="getPattern()"
           required>
          

          在控制器中:

          //Escape the special chars
              $scope.getPattern = function(){
                  return $scope.user.password && 
                        $scope.user.password.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1');
              }
          

          http://plnkr.co/edit/QDTnipCsHdg56vgygsqC?p=preview

          【讨论】:

            【解决方案15】:

            以下是我对这个问题的看法。该指令将与表单值而不是范围进行比较。

            'use strict';
            (function () {
                angular.module('....').directive('equals', function ($timeout) {
                    return {
                        restrict: 'A',
                        require: ['^form', 'ngModel'],
                        scope: false,
                        link: function ($scope, elem, attrs, controllers) {
                            var validationKey = 'equals';
                            var form = controllers[0];
                            var ngModel = controllers[1];
            
                            if (!ngModel) {
                                return;
                            }
            
                            //run after view has rendered
                            $timeout(function(){
                                $scope.$watch(attrs.ngModel, validate);
            
                                $scope.$watch(form[attrs.equals], validate);
                            }, 0);
            
                            var validate = function () {
                                var value1 = ngModel.$viewValue;
                                var value2 = form[attrs.equals].$viewValue;
                                var validity = !value1 || !value2 || value1 === value2;
                                ngModel.$setValidity(validationKey, validity);
                                form[attrs.equals].$setValidity(validationKey,validity);
                            };
                        }
                    };
                });
            })();
            

            在 HTML 中,现在指的是实际表单而不是作用域值:

            <form name="myForm">
              <input type="text" name="value1" equals="value2">
              <input type="text" name="value2" equals="value1">
              <div ng-show="myForm.$invalid">The form is invalid!</div>
            </form>
            

            【讨论】:

            • 看起来好像不能看到表单值,所以我认为 $scope.$watch(form[attrs.equals], validate); 从未真正被调用过。否则,仅在一个元素上具有 equals 属性就足够了。
            【解决方案16】:

            为了在两个输入都更改时实现验证,我使用以下代码(它是所有其他答案的组合):

            angular.module('app.directives')
            .directive('passwordVerify', [function () {
                return {
                    require: '?ngModel',
                    restrict: 'A',
                    scope: {
                        origin: '=passwordVerify'
                    },
                    link: function (scope, element, attrs, ctrl) {
                        if(!ctrl) {
                            return;
                        }
            
                        function validate(value) {
                            ctrl.$setValidity('passwordMatch', scope.origin === value);
                            return value;
                        }
            
                        ctrl.$parsers.unshift(validate);
            
                        scope.$watch('origin', function(value) {
                            validate(ctrl.$viewValue);
                        });
                    }
                };
            }]);
            

            【讨论】:

              【解决方案17】:

              首先,我要感谢 Fredric 发布了这个出色的示例。我偶然发现了一个小问题。在你发布的小提琴上http://jsfiddle.net/gUSZS/

              如果您输入密码,然后在验证输入元素中输入相同的密码,一切正常,但尝试在第二个框中添加一个空格,Angular 会自动修剪该空格。这意味着该指令不会“看到”额外的空间。现在密码不同了,但表单仍然有效。

              为了解决这个问题,我们需要添加

              ng-trim="false"
              

              到输入元素。这在 angular 1.0.3 中不起作用,所以如果你想在这个 fiddle 中尝试它,你需要将 1.1.1 添加到 Fiddle (http://ajax.googleapis.com/ajax/libs/angularjs/1.1.1/angular.js)

              但再次感谢 Frederic,我将在我的应用程序中使用您的解决方案!

              安东 附:我想评论 Frederic 的帖子,但我是这个论坛的新手,似乎没有足够的信誉。因此,如果你们中的一些人喜欢我的评论,我们将不胜感激:-)

              【讨论】:

                【解决方案18】:

                不需要额外的指令,这是我的看法:

                HTML:

                <div class="form-group" data-ng-class="{ 'has-error': submitted && !form.new_passwd.$valid }">
                    <input type="password" name="new_passwd" class="form-control" data-ng-model="data.new_passwd" placeholder="New Password" required data-ng-pattern="passwdRegex">
                    <small class="help-block" data-ng-show="submitted && form.new_passwd.$error.required">New password is required!</small>
                    <small class="help-block" data-ng-show="submitted && !form.new_passwd.$error.required && form.new_passwd.$error.pattern">New password is not strong enough!</small>
                </div>
                
                <div class="form-group" data-ng-class="{ 'has-error': submitted && !form.new_passwd_conf.$valid }">
                    <input type="password" name="new_passwd_conf" class="form-control" data-ng-model="data.new_passwd_conf" placeholder="Confirm New Password" required data-ng-pattern="passwdConfRegex">
                    <small class="help-block" data-ng-show="submitted && form.new_passwd_conf.$error.required">New password confirmation is required!</small>
                    <small class="help-block" data-ng-show="submitted && !form.new_passwd_conf.$error.required && form.new_passwd_conf.$error.pattern">New password confirmation does not match!</small>
                </div>
                

                Javascript:

                $scope.passwdRegex = /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,}$/;
                $scope.$watch('data.new_passwd', function() {
                    $scope.passwdConfRegex = new RegExp(Regex.escape($scope.data.new_passwd));
                });
                

                在哪里可以找到 Regex.escape() here

                像魅力一样工作!

                【讨论】:

                • 我用 jsfiddle 试过了,不行,你能整理一下给我们看看吗?
                【解决方案19】:

                要添加到大量现有的解决方案,这对我很有效。

                Jan Laussmann 回答停止使用最新的 AngularJS beta 版本)。

                指令:

                angular.module('myApp').directive('matchValidator', [function() {
                        return {
                            require: 'ngModel',
                            link: function(scope, elm, attr, ctrl) {
                                var pwdWidget = elm.inheritedData('$formController')[attr.matchValidator];
                
                                ctrl.$parsers.push(function(value) {
                                    if (value === pwdWidget.$viewValue) {
                                        ctrl.$setValidity('match', true); 
                                        return value;
                                    }                       
                
                                    if (value && pwdWidget.$viewValue) {
                                        ctrl.$setValidity('match', false);
                                    }
                
                                });
                
                                pwdWidget.$parsers.push(function(value) {
                                    if (value && ctrl.$viewValue) {
                                        ctrl.$setValidity('match', value === ctrl.$viewValue);
                                    }
                                    return value;
                                });
                            }
                        };
                    }])
                

                用法

                <input type="email" ng-model="value1" name="email" required>
                <input type="email" ng-model="value2" name="emailConfirm" match-validator="email" required>
                

                显示错误

                <div ng-if="[[yourFormName]].emailConfirm.$error">
                    <div ng-if="[[yourFormName]].emailConfirm.$error.match">
                        Email addresses don't match.
                    </div>
                </div>
                

                【讨论】:

                  【解决方案20】:
                     <input name="password" type="text" required="" ng-model="password" placeholder="password" class="ng-dirty ng-valid ng-valid-required">
                     <input name="confirm_password" type="text" required="" ng-model="confirm_password" ui-validate=" '$value==password' " ui-validate-watch=" 'password' " placeholder="confirm password" class="ng-dirty ng-valid-required ng-invalid ng-invalid-validator"> 
                     <span ng-show="form.confirm_password.$error.validator">Passwords do not match!</span>
                          password errors: {
                          "required": false,
                          "validator": true
                          }
                  

                  【讨论】:

                    【解决方案21】:

                    这对我有用。

                    指令:

                    modulename.directive('passwordCheck', 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
                    
                                var Value = null;
                    
                                // watch own value and re-validate on change
                                scope.$watch(attrs.ngModel, function (val) {
                                    Value = val;
                    
                    
                                    validate();
                                });
                    
                                // observe the other value and re-validate on change
                                attrs.$observe('passwordCheck', function () {
                                    validate();
                                });
                    
                                var validate = function () {
                    
                                    // values
                                    var val1 = Value;
                                    var val2 = attrs.passwordCheck;
                    
                                    // set validity
                    
                                    if (val1 != '' && val1 != undefined) {
                                        ngModel.$setValidity('passwordCheck', val1 == val2);
                    
                                    }
                    
                                    else {
                                        ngModel.$setValidity('passwordCheck', true);
                                    }
                                };
                            }
                        }
                    });
                    

                    HTML:

                    ng-model="confirmpassword.selected" type="password" name="confirmpassword" 
                    
                    password-check="{{password.selected}}"
                    
                    ng-show="resetpasswordform.confirmpassword.$error.passwordCheck && submitted" Password does not match
                    

                    【讨论】:

                      【解决方案22】:

                      我在尝试构建自己的指令时遇到了同样的问题,我用这个添加修复了

                      ctrl.$validate();

                      其中 ctrl 是我的 ngModelController

                      这是我的看法

                      <input type="password" match="signupCtrl.registrationData.password" name="confirmPassword" class="form-control" placeholder="Confirm Password" data-ng-model="signupCtrl.registrationData.confirmPassword" required>
                              <span ng-messages="registerForm.confirmPassword.$error">
                                  <span ng-message="match">The Password must match</span>
                              </span>
                      

                      这是我的指令

                      (function () {
                          'use strict';
                          angular.module('matchDirective', [
                              // Angular modules
                              // Custom modules
                              // 3rd Party Modules
                          ]);
                      })(); 
                      (function () {
                          'use strict';
                          angular
                              .module('matchDirective')
                              .directive('match', match);
                          match.$inject = ['$window'];
                      
                          function match($window) {
                              // Usage:
                              //     <element match="source"></element>
                              // Creates:
                              //
                              var directive = {
                                  link: link,
                                  restrict: 'A',
                                  require: 'ngModel',
                              };
                              return directive;
                      
                              function link(scope, element, attrs, ctrl) {
                                  scope.$watch(attrs['match'], function (newVal, oldVal) {
                                      ctrl.$validators.match = function (modelValue, viewValue) {
                                          if (newVal == modelValue) {
                                              return true;
                                          } else {
                                              return false;
                                          }
                                      }
                                      ctrl.$validate();
                                  });
                              }
                          }
                      })();
                      

                      【讨论】:

                        【解决方案23】:

                        这样的东西对我有用:

                        js:

                        .directive('sameAs', function() { return {
                            require : 'ngModel',
                            link : function(scope, elm, attrs, ngModelCtrl) {
                        
                                ngModelCtrl.$validators.sameAs = function(modelValue, viewValue) {
                                    var checkedVal = attrs.sameAs;
                                    var thisInputVal = viewValue;
                        
                                    if (thisInputVal == checkedVal) {
                                        return true; // valid
                                    } else {
                                        return false;
                                    }
                                };
                            }
                        }; });
                        

                        html:

                        <input type="password" name="password" id="password" ng-model="password" />
                        
                        <input type="password" name="passwordRepeat" id="passwordRepeat" 
                            ng-model="passwordRepeat" same-as="{{password}}" />
                        

                        【讨论】:

                          【解决方案24】:

                          保持简单和愚蠢(KISS)原则可能对这一点有用。通过执行以下操作可以更快、更轻松地检查两个密码是否匹配:

                          <div ng-app="app" ng-controller="passwordCheck">
                            <form name="signUp" ng-submit="submitForm()" novalidate>
                               <input type="password" name="password" ng-model="password" required>
                               <input type="password" name="ConfirmPassword" ng-model="passwordconfirm"   required>
                               <button type="submit"> Submit</button>
                            </form>
                          
                            <hr>
                            <span>Do they match?</span> {{signUp.password.$viewValue == signUp.confirmPassword.$viewValue}}
                              </div>
                          

                          并且在提交表单之前,你可以在你的js中这样做

                          var app = angular.module("app", []);
                          app.controller("passwordCheck", function($scope) {
                             $scope.submitForm = function() {
                                if ($scope.signUp.$valid && $scope.signUp.password.$viewValue == $scope.signUp.confirmPassword.$viewValue) {
                                      alert('Its a match!');
                                  };
                          };
                          });
                          

                          您也可以在JSfiddle 中进行测试。

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 2017-10-29
                            • 2014-12-03
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2014-11-01
                            相关资源
                            最近更新 更多