From 89f3e3b0af74d6ea2f2741b4d6eced184e1a2b1a Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Thu, 26 Jan 2017 13:29:11 +0100 Subject: [PATCH] fix(select): keep ngModel when selected option is recreated by ngRepeat Fixes #15630 Closes #15632 --- src/ng/directive/select.js | 2 +- test/ng/directive/selectSpec.js | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js index ed7400d57..0c8201068 100644 --- a/src/ng/directive/select.js +++ b/src/ng/directive/select.js @@ -281,7 +281,7 @@ var SelectController = var removeValue = optionAttrs.value; self.removeOption(removeValue); - self.ngModelCtrl.$render(); + scheduleRender(); if (self.multiple && currentValue && currentValue.indexOf(removeValue) !== -1 || currentValue === removeValue diff --git a/test/ng/directive/selectSpec.js b/test/ng/directive/selectSpec.js index 9596d3b4d..e77d5bffc 100644 --- a/test/ng/directive/selectSpec.js +++ b/test/ng/directive/selectSpec.js @@ -2316,6 +2316,40 @@ describe('select', function() { }); + it('should keep the ngModel value when the selected option is recreated by ngRepeat', function() { + scope.options = [{ name: 'A'}, { name: 'B'}, { name: 'C'}]; + scope.obj = { + value: 'B' + }; + + compile( + '' + ); + + var optionElements = element.find('option'); + expect(optionElements.length).toEqual(3); + expect(optionElements[0].value).toBe('A'); + expect(optionElements[1]).toBeMarkedAsSelected(); + expect(scope.obj.value).toBe('B'); + + scope.$apply(function() { + // Only when new objects are used, ngRepeat re-creates the element from scratch + scope.options = [{ name: 'B'}, { name: 'C'}, { name: 'D'}]; + }); + + var previouslySelectedOptionElement = optionElements[1]; + optionElements = element.find('option'); + + expect(optionElements.length).toEqual(3); + expect(optionElements[0].value).toBe('B'); + expect(optionElements[0]).toBeMarkedAsSelected(); + expect(scope.obj.value).toBe('B'); + // Ensure the assumption that the element is re-created is true + expect(previouslySelectedOptionElement).not.toBe(optionElements[0]); + }); + });