Skip to content

Commit 91ea1a1

Browse files
crisbetojelbourn
authored andcommitted
fix(selection-list): preselected options not being added to the model value (#9116)
Fixes preselected list options not being added to the model due to: * The `Promise.resolve` inside the `ngOnInit` not actually doing anything due to a missing `.then`. * The option not being added to the selection model when the value is emitted, which means that it won't be a part of the model.
1 parent ff1c5f1 commit 91ea1a1

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

src/lib/list/selection-list.spec.ts

+55-1
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,9 @@ describe('MatSelectionList with forms', () => {
572572
imports: [MatListModule, FormsModule, ReactiveFormsModule],
573573
declarations: [
574574
SelectionListWithModel,
575-
SelectionListWithFormControl
575+
SelectionListWithFormControl,
576+
SelectionListWithPreselectedOption,
577+
SelectionListWithPreselectedOptionAndModel
576578
]
577579
});
578580

@@ -735,6 +737,34 @@ describe('MatSelectionList with forms', () => {
735737
expect(listOptions[2].selected).toBe(true, 'Expected third option to be selected.');
736738
});
737739
});
740+
741+
describe('preselected values', () => {
742+
it('should add preselected options to the model value', fakeAsync(() => {
743+
const fixture = TestBed.createComponent(SelectionListWithPreselectedOption);
744+
const listOptions = fixture.debugElement.queryAll(By.directive(MatListOption))
745+
.map(optionDebugEl => optionDebugEl.componentInstance);
746+
747+
fixture.detectChanges();
748+
tick();
749+
750+
expect(listOptions[1].selected).toBe(true);
751+
expect(fixture.componentInstance.selectedOptions).toEqual(['opt2']);
752+
}));
753+
754+
it('should handle preselected option both through the model and the view', fakeAsync(() => {
755+
const fixture = TestBed.createComponent(SelectionListWithPreselectedOptionAndModel);
756+
const listOptions = fixture.debugElement.queryAll(By.directive(MatListOption))
757+
.map(optionDebugEl => optionDebugEl.componentInstance);
758+
759+
fixture.detectChanges();
760+
tick();
761+
762+
expect(listOptions[0].selected).toBe(true);
763+
expect(listOptions[1].selected).toBe(true);
764+
expect(fixture.componentInstance.selectedOptions).toEqual(['opt1', 'opt2']);
765+
}));
766+
767+
});
738768
});
739769

740770

@@ -858,3 +888,27 @@ class SelectionListWithModel {
858888
class SelectionListWithFormControl {
859889
formControl = new FormControl();
860890
}
891+
892+
893+
@Component({
894+
template: `
895+
<mat-selection-list [(ngModel)]="selectedOptions">
896+
<mat-list-option value="opt1">Option 1</mat-list-option>
897+
<mat-list-option value="opt2" selected>Option 2</mat-list-option>
898+
</mat-selection-list>`
899+
})
900+
class SelectionListWithPreselectedOption {
901+
selectedOptions: string[];
902+
}
903+
904+
905+
@Component({
906+
template: `
907+
<mat-selection-list [(ngModel)]="selectedOptions">
908+
<mat-list-option value="opt1">Option 1</mat-list-option>
909+
<mat-list-option value="opt2" selected>Option 2</mat-list-option>
910+
</mat-selection-list>`
911+
})
912+
class SelectionListWithPreselectedOptionAndModel {
913+
selectedOptions = ['opt1'];
914+
}

src/lib/list/selection-list.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,13 @@ export class MatListOption extends _MatListOptionMixinBase
163163
}
164164

165165
ngOnInit() {
166-
if (this.selected) {
166+
if (this._selected) {
167167
// List options that are selected at initialization can't be reported properly to the form
168168
// control. This is because it takes some time until the selection-list knows about all
169169
// available options. Also it can happen that the ControlValueAccessor has an initial value
170170
// that should be used instead. Deferring the value change report to the next tick ensures
171171
// that the form control value is not being overwritten.
172-
Promise.resolve(() => this.selected && this.selectionList._reportValueChange());
172+
Promise.resolve().then(() => this.selected = true);
173173
}
174174
}
175175

0 commit comments

Comments
 (0)