From 91ea1a121c1539063d0c4f3521f82990ee945455 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 5 Jan 2018 00:02:28 +0200 Subject: [PATCH] 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. --- src/lib/list/selection-list.spec.ts | 56 ++++++++++++++++++++++++++++- src/lib/list/selection-list.ts | 4 +-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/lib/list/selection-list.spec.ts b/src/lib/list/selection-list.spec.ts index 216c3760abb3..b31c1ed5ec2c 100644 --- a/src/lib/list/selection-list.spec.ts +++ b/src/lib/list/selection-list.spec.ts @@ -572,7 +572,9 @@ describe('MatSelectionList with forms', () => { imports: [MatListModule, FormsModule, ReactiveFormsModule], declarations: [ SelectionListWithModel, - SelectionListWithFormControl + SelectionListWithFormControl, + SelectionListWithPreselectedOption, + SelectionListWithPreselectedOptionAndModel ] }); @@ -735,6 +737,34 @@ describe('MatSelectionList with forms', () => { expect(listOptions[2].selected).toBe(true, 'Expected third option to be selected.'); }); }); + + describe('preselected values', () => { + it('should add preselected options to the model value', fakeAsync(() => { + const fixture = TestBed.createComponent(SelectionListWithPreselectedOption); + const listOptions = fixture.debugElement.queryAll(By.directive(MatListOption)) + .map(optionDebugEl => optionDebugEl.componentInstance); + + fixture.detectChanges(); + tick(); + + expect(listOptions[1].selected).toBe(true); + expect(fixture.componentInstance.selectedOptions).toEqual(['opt2']); + })); + + it('should handle preselected option both through the model and the view', fakeAsync(() => { + const fixture = TestBed.createComponent(SelectionListWithPreselectedOptionAndModel); + const listOptions = fixture.debugElement.queryAll(By.directive(MatListOption)) + .map(optionDebugEl => optionDebugEl.componentInstance); + + fixture.detectChanges(); + tick(); + + expect(listOptions[0].selected).toBe(true); + expect(listOptions[1].selected).toBe(true); + expect(fixture.componentInstance.selectedOptions).toEqual(['opt1', 'opt2']); + })); + + }); }); @@ -858,3 +888,27 @@ class SelectionListWithModel { class SelectionListWithFormControl { formControl = new FormControl(); } + + +@Component({ + template: ` + + Option 1 + Option 2 + ` +}) +class SelectionListWithPreselectedOption { + selectedOptions: string[]; +} + + +@Component({ + template: ` + + Option 1 + Option 2 + ` +}) +class SelectionListWithPreselectedOptionAndModel { + selectedOptions = ['opt1']; +} diff --git a/src/lib/list/selection-list.ts b/src/lib/list/selection-list.ts index 02849ebd3d2b..0e9ce47bd3df 100644 --- a/src/lib/list/selection-list.ts +++ b/src/lib/list/selection-list.ts @@ -163,13 +163,13 @@ export class MatListOption extends _MatListOptionMixinBase } ngOnInit() { - if (this.selected) { + if (this._selected) { // List options that are selected at initialization can't be reported properly to the form // control. This is because it takes some time until the selection-list knows about all // available options. Also it can happen that the ControlValueAccessor has an initial value // that should be used instead. Deferring the value change report to the next tick ensures // that the form control value is not being overwritten. - Promise.resolve(() => this.selected && this.selectionList._reportValueChange()); + Promise.resolve().then(() => this.selected = true); } }