fix(ngOptions): don't duplicate groups with falsy values

Previously, ngOptions would fail to remove optgroups with falsy values when the options were changed / removed.

Related #14781 
PR (#14784)
This commit is contained in:
Martin Staffa
2016-06-15 19:39:16 +02:00
committed by GitHub
parent bb4cd4a5ce
commit 6bc81ae6ef
2 changed files with 84 additions and 2 deletions
+3 -2
View File
@@ -629,7 +629,7 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
for (var i = options.items.length - 1; i >= 0; i--) {
var option = options.items[i];
if (option.group) {
if (isDefined(option.group)) {
jqLiteRemove(option.element.parentNode);
} else {
jqLiteRemove(option.element);
@@ -661,7 +661,8 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
listFragment.appendChild(groupElement);
// Update the label on the group element
groupElement.label = option.group;
// "null" is special cased because of Safari
groupElement.label = option.group === null ? 'null' : option.group;
// Store it for use later
groupElementMap[option.group] = groupElement;
+81
View File
@@ -1789,6 +1789,87 @@ describe('ngOptions', function() {
});
it('should group if the group has a falsy value (except undefined)', function() {
createSelect({
'ng-model': 'selected',
'ng-options': 'item.name group by item.group for item in values'
});
scope.$apply(function() {
scope.values = [{name: 'A'},
{name: 'B', group: ''},
{name: 'C', group: null},
{name: 'D', group: false},
{name: 'E', group: 0}];
scope.selected = scope.values[0];
});
var optgroups = element.find('optgroup');
var options = element.find('option');
expect(optgroups.length).toEqual(4);
expect(options.length).toEqual(5);
expect(optgroups[0].label).toBe('');
expect(optgroups[1].label).toBe('null');
expect(optgroups[2].label).toBe('false');
expect(optgroups[3].label).toBe('0');
expect(options[0].textContent).toBe('A');
expect(options[0].parentNode).toBe(element[0]);
expect(options[1].textContent).toBe('B');
expect(options[1].parentNode).toBe(optgroups[0]);
expect(options[2].textContent).toBe('C');
expect(options[2].parentNode).toBe(optgroups[1]);
expect(options[3].textContent).toBe('D');
expect(options[3].parentNode).toBe(optgroups[2]);
expect(options[4].textContent).toBe('E');
expect(options[4].parentNode).toBe(optgroups[3]);
});
it('should not duplicate a group with a falsy value when the options are updated', function() {
scope.$apply(function() {
scope.values = [{value: 'A', group: ''},
{value: 'B', group: 'First'}];
scope.selected = scope.values[0];
});
createSelect({
'ng-model': 'selected',
'ng-options': 'item.value group by item.group for item in values'
});
scope.$apply(function() {
scope.values.push({value: 'C', group: false});
});
var optgroups = element.find('optgroup');
var options = element.find('option');
expect(optgroups.length).toEqual(3);
expect(options.length).toEqual(3);
expect(optgroups[0].label).toBe('');
expect(optgroups[1].label).toBe('First');
expect(optgroups[2].label).toBe('false');
expect(options[0].textContent).toBe('A');
expect(options[0].parentNode).toBe(optgroups[0]);
expect(options[1].textContent).toBe('B');
expect(options[1].parentNode).toBe(optgroups[1]);
expect(options[2].textContent).toBe('C');
expect(options[2].parentNode).toBe(optgroups[2]);
});
it('should bind to scope value and track/identify objects', function() {
createSelect({
'ng-model': 'selected',