From fb1130ac3b87280a4f4e99b61b335f6f87cf3144 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Wed, 7 Oct 2015 13:19:11 +0100 Subject: [PATCH] fix(ngOptions) skip authentic empty options when looking for options Related #12952 Closes #12190 Closes #13029 --- src/ng/directive/ngOptions.js | 13 +++++++-- test/ng/directive/ngOptionsSpec.js | 46 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/ng/directive/ngOptions.js b/src/ng/directive/ngOptions.js index 26f2f0cf1904..04a0094c6bb3 100644 --- a/src/ng/directive/ngOptions.js +++ b/src/ng/directive/ngOptions.js @@ -408,7 +408,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) { } } - var providedEmptyOption = !!emptyOption; + var providedEmptyOption = emptyOption; var unknownOption = jqLite(optionTemplate.cloneNode(false)); unknownOption.val('?'); @@ -618,10 +618,19 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) { var emptyOption_ = emptyOption && emptyOption[0]; var unknownOption_ = unknownOption && unknownOption[0]; + // If the compiled empty option was replaced by a comment because + // it had an "element" transclusion directive on it (such as ngIf) + // then compare against the pre-compiled empty element instead + if (emptyOption && emptyOption_.nodeType === NODE_TYPE_COMMENT) { + emptyOption_ = providedEmptyOption[0]; + } + if (emptyOption_ || unknownOption_) { while (current && (current === emptyOption_ || - current === unknownOption_)) { + current === unknownOption_ || + current.nodeType === NODE_TYPE_COMMENT || + current.value === '')) { current = current.nextSibling; } } diff --git a/test/ng/directive/ngOptionsSpec.js b/test/ng/directive/ngOptionsSpec.js index c5dac4b72914..09b4dd26e943 100644 --- a/test/ng/directive/ngOptionsSpec.js +++ b/test/ng/directive/ngOptionsSpec.js @@ -2144,6 +2144,52 @@ describe('ngOptions', function() { }); + it('should be possible to use ngIf in the blank option', function() { + var option; + createSingleSelect(''); + + scope.$apply(function() { + scope.values = [{name: 'A'}]; + scope.isBlank = true; + }); + + expect(element.find('option').length).toBe(2); + option = element.find('option').eq(0); + expect(option.val()).toBe(''); + expect(option.text()).toBe('blank'); + + scope.$apply(function() { + scope.isBlank = false; + }); + + expect(element.find('option').length).toBe(1); + option = element.find('option').eq(0); + expect(option.text()).toBe('A'); + }); + + + it('should be possible to use ngIf in the blank option when values are available upon linking', + function() { + var options; + + scope.values = [{name: 'A'}]; + createSingleSelect(''); + + scope.$apply('isBlank = true'); + + options = element.find('option'); + expect(options.length).toBe(2); + expect(options.eq(0).val()).toBe(''); + expect(options.eq(0).text()).toBe('blank'); + + scope.$apply('isBlank = false'); + + options = element.find('option'); + expect(options.length).toBe(1); + expect(options.eq(0).text()).toBe('A'); + } + ); + it('should not throw when a directive compiles the blank option before ngOptions is linked', function() { expect(function() { createSelect({