From 42a9eca341672f69c4219d9bc44f7ac3340c07e0 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 | 14 ++++++++++++++ 2 files changed, 19 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..a851b2fec95c 100644 --- a/test/ng/directive/validatorsSpec.js +++ b/test/ng/directive/validatorsSpec.js @@ -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( + '
' + + '' + + '
'); + + expect(helper.validationCounter.required).toBe(1); + expect($rootScope.refs.input.$error.required).toBeUndefined(); + }); + }); });