From 2d7e08efec577acd371f309cc3ba3c082847c06b Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Fri, 20 Jan 2017 18:07:04 +0100 Subject: [PATCH 1/4] fix(select): keep ngModel when selected option is recreated with ngRepeat Fixes #15630 --- src/ng/directive/select.js | 2 +- test/ng/directive/selectSpec.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js index ed7400d570bc..0c8201068c29 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 9596d3b4d792..4b4f69231a23 100644 --- a/test/ng/directive/selectSpec.js +++ b/test/ng/directive/selectSpec.js @@ -2316,6 +2316,34 @@ describe('select', function() { }); + it('should keep the ngModel value when the selected option is recreated by ngRepeat', function() { + + scope.options = ['A', 'B', '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(); + + scope.$apply(function() { + scope.options = ['B', 'C', 'D']; + }); + + optionElements = element.find('option'); + expect(optionElements.length).toEqual(3); + expect(optionElements[0].value).toBe('B'); + expect(optionElements[0]).toBeMarkedAsSelected(); + }); + }); From a4e026f1237b6fb95b48bfc5c7edd7ffed7c6ec0 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Fri, 20 Jan 2017 18:31:35 +0100 Subject: [PATCH 2/4] fixup! fix expectations --- test/ng/directive/selectSpec.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/ng/directive/selectSpec.js b/test/ng/directive/selectSpec.js index 4b4f69231a23..7d23bf58114a 100644 --- a/test/ng/directive/selectSpec.js +++ b/test/ng/directive/selectSpec.js @@ -2317,15 +2317,14 @@ describe('select', function() { }); it('should keep the ngModel value when the selected option is recreated by ngRepeat', function() { - - scope.options = ['A', 'B', 'C']; + scope.options = [{ name: 'A'}, { name: 'B'}, { name: 'C'}]; scope.obj = { value: 'B' }; compile( '' ); @@ -2333,15 +2332,18 @@ describe('select', function() { expect(optionElements.length).toEqual(3); expect(optionElements[0].value).toBe('A'); expect(optionElements[1]).toBeMarkedAsSelected(); + expect(scope.obj.value).toBe('B'); scope.$apply(function() { - scope.options = ['B', 'C', 'D']; + // Only when new objects are used, ngRepeat re-creates the element from scratch + scope.options = [{ name: 'B'}, { name: 'C'}, { name: 'D'}]; }); 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'); }); }); From c330b9c4d6a5462daca9cd106b7059fdee647997 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Wed, 25 Jan 2017 17:02:35 +0100 Subject: [PATCH 3/4] fixup! add another expectation --- test/ng/directive/selectSpec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/ng/directive/selectSpec.js b/test/ng/directive/selectSpec.js index 7d23bf58114a..d609608f4aa0 100644 --- a/test/ng/directive/selectSpec.js +++ b/test/ng/directive/selectSpec.js @@ -2339,11 +2339,15 @@ describe('select', function() { 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]); }); }); From cba11789b94243fe6bd624b7531e8ea616f8b8f6 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Thu, 26 Jan 2017 12:27:09 +0100 Subject: [PATCH 4/4] fixup! fix newline --- test/ng/directive/selectSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ng/directive/selectSpec.js b/test/ng/directive/selectSpec.js index d609608f4aa0..e77d5bffcf3f 100644 --- a/test/ng/directive/selectSpec.js +++ b/test/ng/directive/selectSpec.js @@ -2341,8 +2341,8 @@ describe('select', function() { var previouslySelectedOptionElement = optionElements[1]; optionElements = element.find('option'); - expect(optionElements.length).toEqual(3); + expect(optionElements.length).toEqual(3); expect(optionElements[0].value).toBe('B'); expect(optionElements[0]).toBeMarkedAsSelected(); expect(scope.obj.value).toBe('B');