diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js index e44b61e955cb..08d75174371a 100644 --- a/src/ng/directive/select.js +++ b/src/ng/directive/select.js @@ -392,6 +392,12 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { value = valueFn(scope, locals); } } + // Update the null option's selected property here so $render cleans it up correctly + if (optionGroupsCache[0].length > 1) { + if (optionGroupsCache[0][1].id !== key) { + optionGroupsCache[0][1].selected = false; + } + } } ctrl.$setViewValue(value); }); @@ -529,7 +535,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) { lastElement.val(existingOption.id = option.id); } // lastElement.prop('selected') provided by jQuery has side-effects - if (lastElement[0].selected !== option.selected) { + if (existingOption.selected !== option.selected) { lastElement.prop('selected', (existingOption.selected = option.selected)); } } else { diff --git a/test/ng/directive/selectSpec.js b/test/ng/directive/selectSpec.js index 6fcd1fe05f82..c251dbc37526 100644 --- a/test/ng/directive/selectSpec.js +++ b/test/ng/directive/selectSpec.js @@ -733,6 +733,27 @@ describe('select', function() { expect(sortedHtml(options[2])).toEqual(''); }); + it('should not update selected property of an option element on digest with no change event', + function() { + createSingleSelect(); + + scope.$apply(function() { + scope.values = [{name: 'A'}, {name: 'B'}, {name: 'C'}]; + scope.selected = scope.values[0]; + }); + + var options = element.find('option'); + var optionToSelect = options.eq(1); + + expect(optionToSelect.text()).toBe('B'); + + optionToSelect.prop('selected', true); + scope.$digest(); + + expect(optionToSelect.prop('selected')).toBe(true); + expect(scope.selected).toBe(scope.values[0]); + }); + describe('binding', function() { it('should bind to scope value', function() {