From b09d16a0472a8d54c3cfe34e2044586884af93c4 Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Wed, 30 Nov 2016 11:32:19 -0800 Subject: [PATCH] fix(select): fix initial values with reactive forms Closes #1973 --- src/demo-app/select/select-demo.ts | 2 +- src/lib/select/select.spec.ts | 21 +++++++++++++++++++++ src/lib/select/select.ts | 9 +++++++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/demo-app/select/select-demo.ts b/src/demo-app/select/select-demo.ts index f7bec82ca09d..7bd1c6cda590 100644 --- a/src/demo-app/select/select-demo.ts +++ b/src/demo-app/select/select-demo.ts @@ -11,7 +11,7 @@ export class SelectDemo { isRequired = false; isDisabled = false; currentDrink: string; - foodControl = new FormControl(''); + foodControl = new FormControl('pizza-1'); foods = [ {value: 'steak-0', viewValue: 'Steak'}, diff --git a/src/lib/select/select.spec.ts b/src/lib/select/select.spec.ts index 3e05ceffe0fa..22073f8cfef7 100644 --- a/src/lib/select/select.spec.ts +++ b/src/lib/select/select.spec.ts @@ -244,8 +244,29 @@ describe('MdSelect', () => { beforeEach(() => { fixture = TestBed.createComponent(BasicSelect); + }); + + it('should take an initial view value', () => { + fixture.componentInstance.control = new FormControl('pizza-1'); + fixture.detectChanges(); + + const value = fixture.debugElement.query(By.css('.md-select-value')); + expect(value.nativeElement.textContent) + .toContain('Pizza', `Expected trigger to be populated by the control's initial value.`); + + trigger = fixture.debugElement.query(By.css('.md-select-trigger')).nativeElement; + trigger.click(); fixture.detectChanges(); + const options = + overlayContainerElement.querySelectorAll('md-option') as NodeListOf; + expect(options[1].classList) + .toContain('md-selected', + `Expected option with the control's initial value to be selected.`); + }); + + beforeEach(() => { + fixture.detectChanges(); trigger = fixture.debugElement.query(By.css('.md-select-trigger')).nativeElement; }); diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index 19ae9817c9da..a3a9a14c89a1 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -5,6 +5,7 @@ import { ElementRef, EventEmitter, Input, + NgZone, OnDestroy, Optional, Output, @@ -133,7 +134,8 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr @Output() onClose = new EventEmitter(); constructor(private _element: ElementRef, private _renderer: Renderer, - @Optional() private _dir: Dir, @Optional() public _control: NgControl) { + @Optional() private _dir: Dir, @Optional() public _control: NgControl, + private _ngZone: NgZone) { if (this._control) { this._control.valueAccessor = this; } @@ -175,7 +177,10 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr * required to integrate with Angular's core forms API. */ writeValue(value: any): void { - if (!this.options) { return; } + if (!this.options) { + this._ngZone.onStable.first().subscribe(() => this.writeValue(value)); + return; + } this.options.forEach((option: MdOption) => { if (option.value === value) {