我目前有一个Angular Directive,用于验证密码并确认密码字段为匹配。它适用于某一点,当密码不匹配时它会抛出错误。但是,在两个字段中输入数据之前,它不会抛出错误。我怎样才能在一个字段或另一个字段中输入数据后立即抛出不匹配密码的错误?
这是指令(必须将其添加到需要匹配的两个字段中):
.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);
};
}
};
});
这是我表格中的指令:
<div class="small-5 columns">
<div class="small-12 columns">
<label>
Password
<input
ng-class="{ notvalid: submitted && add_user_form.user_password.$invalid }"
class="instructor-input"
id="user_password"
type="password"
name='user_password'
placeholder="password"
value=''
required
ng-model="user.user_password"
password-verify="[[user.confirm_password]]"
>
</label>
<p class="help-text">
<span class=" ">Required</span>
</p>
<div
class="help-block"
ng-messages="add_user_form.user_password.$error"
ng-show="add_user_form.user_password.$touched || add_user_form.user_password.$dirty"
>
<span class="red">
<div ng-messages-include="/app/views/messages.html" ></div>
</span>
</div>
</div>
<div class="small-12 columns">
<label>
Confirm Password
<input
ng-class="{ notvalid: submitted && add_user_form.confirm_password.$invalid }"
class="instructor-input"
id="confirm_password"
ng-model="user.confirm_password"
name="confirm_password"
type="password"
placeholder="confirm password"
name="user_confirm_passsword"
required
password-verify="[[user.user_password]]"
>
</label>
<p class="help-text">
<span class=" ">
Enter matching password
</span>
</p>
<div
class="help-block"
ng-messages="add_user_form.confirm_password.$error"
ng-show="add_user_form.confirm_password.$dirty || add_user_form.confirm_password.$touched "
>
<span class="red">
<div
ng-messages-include="/app/views/messages.html"
></div>
</span>
</div>
</div>
答案 0 :(得分:7)
只需更改最后一次检查:
ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2);
以强>
ngModel.$setValidity('passwordVerify', val1 === val2);
这是一个工作版本:
(function() {
"use strict";
angular
.module('app', ['ngMessages'])
.controller('mainCtrl', mainCtrl)
.directive('passwordVerify', passwordVerify);
function mainCtrl($scope) {
// Some code
}
function passwordVerify() {
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);
};
}
}
}
})();
<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.$dirty && 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-if="add_user_form.user_password.$dirty">
<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 class="form-group" ng-class="{ 'has-error' : add_user_form.confirm_password.$dirty && 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-if="add_user_form.confirm_password.$dirty">
<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>
我希望它有所帮助。
答案 1 :(得分:1)
这是一个简单的工作解决方案。我们可以简单地使用Angular 1.3.0中引入的$validators
来实现相同的目标:
var app = angular.module("sa", []);
app.controller("FooController", function($scope) {
});
app.directive('passwordVerify', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elem, attrs, ngModel) {
ngModel.$validators.myPwdInvalid = function(modelValue, viewValue) {
return viewValue === scope.$eval(attrs.passwordVerify);
};
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<form name="add_user_form" ng-app="sa" ng-controller="FooController">
<div class="small-12 columns">
<label>Password
<input ng-class="{ notvalid: add_user_form.user_password.$invalid }"
type="password" name='user_password' placeholder="password" required
ng-model="user.user_password" password-verify="user.confirm_password">
</label>
<div class="help-block" ng-messages="add_user_form.user_password.$error"
ng-show="add_user_form.user_password.$error.$dirty || add_user_form.user_password.$touched">
<div ng-messages="myPwdInvalid">Password do not match</div>
</div>
</div>
<div class="small-12 columns">
<label>Confirm Password
<input ng-class="{ notvalid: add_user_form.confirm_password.$invalid }"
ng-model="user.confirm_password"
name="confirm_password" type="password" placeholder="confirm password" required
password-verify="user.user_password">
</label>
<div class="help-block" ng-messages="add_user_form.confirm_password.$error"
ng-show="add_user_form.confirm_password.$error.$dirty || add_user_form.confirm_password.$touched">
<div ng-messages="myPwdInvalid">Password do not match</div>
</div>
</div>
</form>
答案 2 :(得分:0)
这对我有用(丑陋和hackish):
HTML:
<h1>Password Verification</h1>
<form name="pw" ng-controller="pw">
<p>
<label for="password">New Password
<input type="password" name="user_password" ng-model="user_password" ng-required="confirm_password && !user-password" password-verify="confirm_pasword">
<p ng-show="pw.user_password.$error.passwordVerify">Passwords do not match</p>
<p ng-show="pw.user_password.$error.required">This field is required</p>
</label>
</p>
<p>
<label for="password">Confirm Password
<input type="password" name="confirm_password" ng-model="confirm_password" ng-required="user_password && !confirm_password" password-verify="user_password">
<p ng-show="pw.confirm_password.$error.passwordVerify">Passwords do not match</p>
<p ng-show="pw.confirm_password.$error.required">This field is required</p>
</label>
</p>
</form>
然后是剧本:
angular.module('app', [])
.controller('pw', ['$scope', function($scope){
$scope.user_password = "";
$scope.confirm_password = "";
}])
.directive('passwordVerify', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elem, attrs, ngModel) {
scope.$watch(attrs.ngModel, function() {
if (scope.confirm_password === scope.user_password) {
scope.pw.confirm_password.$setValidity('passwordVerify', true);
scope.pw.user_password.$setValidity('passwordVerify', true);
} else if (scope.confirm_password !== scope.user_password) {
scope.pw.confirm_password.$setValidity('passwordVerify', false);
scope.pw.user_password.$setValidity('passwordVerify', false);
}
});
}
};
});
答案 3 :(得分:0)
这是一个易于理解的解决方案:
<input class="form-control" type="password" name="newpass" ng-model="newpass">
<input class="form-control" type="password" name="confirmpass" ng-model="confirmpass">
<div ng-show="confirmpass != newpass"><hr>Password not matched</div>
答案 4 :(得分:0)
您可以简单地使用以下内容。
<span class="error" ng-if="!register_frm.password.$invalid && !register_frm.confirm_password.$invalid && register_frm.password.$viewValue != register_frm.confirm_password.$viewValue">
Confirm Password must match with Password
</span>
答案 5 :(得分:-1)
虽然上述答案是正确的,但对于这种情况有一个非常简单的解决方案:
您可以使用ng-class
指令设置与angularjs内置类(ng-invalid
)不同的类,并在css中为其添加简单样式。请勿忘记将!important
添加到您的样式中,因为angularjs会覆盖它;)