fix(ngRequired): set error correctly when inside ngRepeat and false by default

Previously, in the required validator, we would read the required setting directly
from attr.required, where it is set by ngRequired.

However, when the control is inside ngRepeat, ngRequired sets it only after a another digest has
passed, which means the initial validation run of ngModel does not include the correct required
setting. (Before commit 0637a2124c this would not have been a problem,
as every observed value change triggered a validation).

We now use the initially parsed value from ngRequired in the validator.

Fixes #16814
Closes #16820
This commit is contained in:
Martin Staffa
2019-01-26 11:31:25 +01:00
committed by Martin Staffa
parent 43bb414e23
commit 5ad4f5562c
2 changed files with 19 additions and 5 deletions
+5 -5
View File
@@ -68,17 +68,17 @@ var requiredDirective = ['$parse', function($parse) {
require: '?ngModel',
link: function(scope, elm, attr, ctrl) {
if (!ctrl) return;
var oldVal = attr.required || $parse(attr.ngRequired)(scope);
var value = attr.required || $parse(attr.ngRequired)(scope);
attr.required = true; // force truthy in case we are on non input element
ctrl.$validators.required = function(modelValue, viewValue) {
return !attr.required || !ctrl.$isEmpty(viewValue);
return !value || !ctrl.$isEmpty(viewValue);
};
attr.$observe('required', function(val) {
if (oldVal !== val) {
oldVal = val;
attr.$observe('required', function(newVal) {
if (value !== newVal) {
value = newVal;
ctrl.$validate();
}
});
+14
View File
@@ -730,5 +730,19 @@ describe('validators', function() {
expect(helper.validationCounter.required).toBe(1);
});
it('should validate once when inside ngRepeat, and set the "required" error when ngRequired is false by default', function() {
$rootScope.isRequired = false;
$rootScope.refs = {};
var elm = helper.compileInput(
'<div ng-repeat="input in [0]">' +
'<input type="text" ng-ref="refs.input" ng-ref-read="ngModel" ng-model="value" ng-required="isRequired" validation-spy="required" />' +
'</div>');
expect(helper.validationCounter.required).toBe(1);
expect($rootScope.refs.input.$error.required).toBeUndefined();
});
});
});