From c3ff2962c2fa85735d13f835b03f766c1857eb5c Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Mon, 21 Jan 2019 12:17:11 +0100 Subject: [PATCH] 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 0637a2124c4515311a317e0e39926521228fc0af 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 --- src/ng/directive/validators.js | 10 +++++----- test/ng/directive/validatorsSpec.js | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/ng/directive/validators.js b/src/ng/directive/validators.js index 85682fb07ea8..5c1649ecf74e 100644 --- a/src/ng/directive/validators.js +++ b/src/ng/directive/validators.js @@ -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(); } }); diff --git a/test/ng/directive/validatorsSpec.js b/test/ng/directive/validatorsSpec.js index 2d89ce8abfce..80892c150cbe 100644 --- a/test/ng/directive/validatorsSpec.js +++ b/test/ng/directive/validatorsSpec.js @@ -730,5 +730,20 @@ 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( + '
' + + '' + + '
' + ); + + expect(helper.validationCounter.required).toBe(1); + expect($rootScope.refs.input.$error.required).toBeUndefined(); + }); + }); });