i'm learning from tutorial "Creating Apps With Angular, Node, and Token Authentication". And i've stuck. I found this code there:
html
<form name="register" class="form-signin" novalidate>
<h1 class="form-signin-heading text-muted">Register</h1>
<input type="email" ng-model="email" name="email"
class="form-control" placeholder="Email address"
required autofocus>
<p class="help-block"
ng-show="register.email.$dirty && register.email.$invalid">
Please enter a proper email.
</p>
<input type="password" name="password" ng-model="password"
class="form-control" placeholder="Password" required>
<input type="password" name="password_confirm" ng-model="password_confirm"
class="form-control" placeholder="Confirm Password"
validate-equals="password">
<p class="help-block"
ng-show="register.password_confirm.$invalid && register.password_confirm.$dirty">
please match the passwords.
</p>
<button ng-disabled="register.$invalid" class="btn btn-lg btn-primary btn-block" type="submit">
Submit
</button>
</form>
and js
angular.module('myApp', []).directive('validateEquals', function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
function validateEqual(value) {
var valid = (value === scope.$eval(attrs.validateEquals));
ngModelCtrl.$setValidity('equal', valid);
return valid ? value : undefined;
}
ngModelCtrl.$parsers.push(validateEqual);
ngModelCtrl.$formatters.push(validateEqual);
scope.$watch(attrs.validateEquals, function() {
ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue);
});
}
};
});
this directive according to the video should give me a proper two-way validation for password
and password_confirm
inputs, but it doesn't (on video it does work, i'm confused). It validates well, when i change value of password_confirm
but when i change password
, validation not work. Here is plunker plunker . Question: What's wrong with that code? And how should i fix it?
The problem probably is in this line:
ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue);
This line doesn't do anything. I gues sthat in a previous version of Angular, it retriggered the $parsers pipeline, and that in the current version, since it sets the view value to the same value that it already has, it has been optimized to not do anything.
This really looks like a hack to me. It should be replaced by something like
scope.$watch(attrs.validateEquals, function(firstPassword) {
var valid = (ngModelCtrl.$modelValue === firstPassword);
ngModelCtrl.$setValidity('equal', valid);
});
(not tested)
BTW, angular now has support for validators, which make things easier and don't force you to deal with parsers and formatters: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController .
Solution found, Thanks to JB Nizet :)
solution :
angular.module('learningAngularApp')
.directive('validateEquals', function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$validators.validateEqual = function(modelValue, viewValue) {
var value = modelValue || viewValue;
var valid = (value === scope.$eval(attrs.validateEquals));
return valid;
}
scope.$watch(attrs.validateEquals, function () {
ngModelCtrl.$validate();
});
}
};
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.