angularjs中的密码检查指令

mpm*_*mpm 76 javascript angularjs

我正在写一个密码验证指令:

 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;
                }
            });

        }
    };
});
Run Code Online (Sandbox Code Playgroud)

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">
Run Code Online (Sandbox Code Playgroud)

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

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

Jan*_*ann 114

我使用以下指令,因为我想重新验证两个输入字段,无论值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);
      };
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

用法

<input type="password" ng-model="value1" equals="{{value2}}" required>
<input type="password" ng-model="value2" equals="{{value1}}" required>
Run Code Online (Sandbox Code Playgroud)

  • 这对我很有用.作为一个新手,它将有助于将验证字符串添加到此.`[表格名称].[字段名称].$ error.equals`用它来控制应该或应该显示哪些字段.我正在将它用于错误标签. (7认同)
  • 我用`if(val1 && val2){..}`包装`ngModel.$ setValidity`,这样当两个值都为空时表单都无效. (5认同)
  • 我发现这个工作得很好.让我措手不及的一件事是,如果你在第一个字段上有一些其他角度验证器:`ng-minlength`,那么在它实际有效之前不会设置该模型 (4认同)
  • 当存在更多验证规则时,这会有一些小问题.如果另一个验证失败,Angular不会更新模型,并且在比较中会发生奇怪的事情...... (4认同)
  • 我认为最好更换```ngModel.$ setValidity('equals',val1 === val2);``````ngModel.$ setValidity('equals',!val1 ||!val2 || val1 === val2);``` (3认同)
  • @JanLaussmann,在转移(删除不相关的东西)我的应用程序到plunker,问题已经消失.这意味着,问题出现在我的代码中.无论如何,我在这里发布了一个带有工作示例的链接.http://plnkr.co/edit/gFmCkUI6A2y4j64OWtrt?p=preview (2认同)

bic*_*cle 85

不需要为此创建单独的指令.Angular UI密码验证工具已经内置了.有了这个,你可以这样做:

<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}}
Run Code Online (Sandbox Code Playgroud)

  • @DominicWatson你在为我做什么?这个问题是关于角度的,我指的是角度文档.如果你不理解它们之间的区别,去学习它. (24认同)
  • @DominicWatson该指令在这里https://github.com/angular-ui/ui-utils/blob/master/modules/validate/validate.js,除了jquery lite之外,其中没有怪异的jquery.如果你是如此反jquery,你不应该使用这个框架,因为它结合了jquery. (24认同)
  • 目前需要jQuery (3认同)
  • 我和原帖有同样的问题.如果已经内置了angular-ui,那么使用它而不是重新发明轮子是否有意义? (3认同)
  • @PeterG我不认为Dominic Watson知道他在说什么 (2认同)

asg*_*oth 60

这应该解决它:

视图:

<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>
Run Code Online (Sandbox Code Playgroud)

指示

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;
                    }
                });
            }
        });
     }
   };
});
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案存在内存泄漏.通过将另一个解析器推送到ctrl.$ parsers数组来触发的每个监视事件.检查监视事件处理程序末尾的ctrl.$ parsers.length将显示此信息. (9认同)

Fre*_*ric 22

另一种观点是将一个输入的模型与另一个输入的值相匹配.

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;
            });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

因此,如果密码框的模型是,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>
Run Code Online (Sandbox Code Playgroud)

扩大的视野:

对于我的一个新项目,我不得不修改上面的指令,这样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;
            });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

你会像这样使用它:

<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>
Run Code Online (Sandbox Code Playgroud)

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

  • 这是最好的.这是最简洁的.它适用于模型值,它可以双向工作. (3认同)

Foy*_*rim 14

我没有指示就完成了.

<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>
Run Code Online (Sandbox Code Playgroud)

  • 您应该使用已经指出的指令,表单保持有效状态.否则你也可以为它做一些jquery监听器. (4认同)

Int*_*lix 8

从角度1.3.0-beta12开始,无效输入不会写入ngModel,因此您无法观看和然后验证,如您所见:http://plnkr.co/edit/W6AFHF308nyKVMQ9vomw?p = preview .引入了一个新的验证器管道,您可以附加到此以实现相同的功能.

实际上,在那个笔记上我已经为常见的额外验证器创建了一个bower组件: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;
            };
        }
    };
});
Run Code Online (Sandbox Code Playgroud)


Mau*_*uro 8

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" />
Run Code Online (Sandbox Code Playgroud)


dma*_*man 7

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

 .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;
        }
      });
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

用法

     <input ... name="password" />
    <input type="password" placeholder="Confirm Password" 
name="password2" ng-model="password2" ng-minlength="9" same-as='password' required>
Run Code Online (Sandbox Code Playgroud)


bic*_*cle 7

我正在处理同样的问题,并发现了一篇关于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;
            });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

所以你可以这样做:

<input type="password" name="repeatPassword" id="repeatPassword" placeholder="repeat password" ng-model="user.repeatPassword" repeat-password="password" required>
Run Code Online (Sandbox Code Playgroud)

归功于作者