fix(select): initial value not being displayed with FormControl and OnPush (#3434)

* fix(select): initial value not being displayed with FormControl and OnPush

Fixes the initial value not being displayed in a select that has a `FormControl` and is placed in a component with `ChangeDetectionStrategy.onPush`.

Relates to https://github.com/angular/material2/issues/2269#issuecomment-283521375.

* chore: remove unused properties
This commit is contained in:
Kristiyan Kostadinov
2017-03-07 01:52:08 +01:00
committed by tinayuangao
parent d06ad753e8
commit 819fa0b51f
2 changed files with 41 additions and 21 deletions
+38 -9
View File
@@ -39,7 +39,8 @@ describe('MdSelect', () => {
FloatPlaceholderSelect,
SelectWithErrorSibling,
ThrowsErrorOnInit,
BasicSelectOnPush
BasicSelectOnPush,
BasicSelectOnPushPreselected
],
providers: [
{provide: OverlayContainer, useFactory: () => {
@@ -1322,16 +1323,25 @@ describe('MdSelect', () => {
});
describe('with OnPush change detection', () => {
let fixture: ComponentFixture<BasicSelectOnPush>;
let trigger: HTMLElement;
it('should set the trigger text based on the value when initialized', async(() => {
let fixture = TestBed.createComponent(BasicSelectOnPushPreselected);
beforeEach(() => {
fixture = TestBed.createComponent(BasicSelectOnPush);
fixture.detectChanges();
trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
});
fixture.whenStable().then(() => {
let trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
fixture.detectChanges();
expect(trigger.textContent).toContain('Pizza');
});
}));
it('should update the trigger based on the value', () => {
let fixture = TestBed.createComponent(BasicSelectOnPush);
fixture.detectChanges();
let trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
fixture.componentInstance.control.setValue('pizza-1');
fixture.detectChanges();
@@ -1342,7 +1352,9 @@ describe('MdSelect', () => {
expect(trigger.textContent).not.toContain('Pizza');
});
});
});
@@ -1561,9 +1573,26 @@ class BasicSelectOnPush {
{ value: 'tacos-2', viewValue: 'Tacos' },
];
control = new FormControl();
}
@ViewChild(MdSelect) select: MdSelect;
@ViewChildren(MdOption) options: QueryList<MdOption>;
@Component({
selector: 'basic-select-on-push-preselected',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<md-select placeholder="Food" [formControl]="control">
<md-option *ngFor="let food of foods" [value]="food.value">
{{ food.viewValue }}
</md-option>
</md-select>
`
})
class BasicSelectOnPushPreselected {
foods: any[] = [
{ value: 'steak-0', viewValue: 'Steak' },
{ value: 'pizza-1', viewValue: 'Pizza' },
{ value: 'tacos-2', viewValue: 'Tacos' },
];
control = new FormControl('pizza-1');
}
@Component({
+3 -12
View File
@@ -313,7 +313,6 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
writeValue(value: any): void {
if (this.options) {
this._setSelectionByValue(value);
this._changeDetectorRef.markForCheck();
}
}
@@ -430,17 +429,9 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
* found with the designated value, the select trigger is cleared.
*/
private _setSelectionByValue(value: any): void {
const options = this.options.toArray();
for (let i = 0; i < this.options.length; i++) {
if (options[i].value === value) {
options[i].select();
return;
}
}
// Clear selection if no item was selected.
this._clearSelection();
const correspondingOption = this.options.find(option => option.value === value);
correspondingOption ? correspondingOption.select() : this._clearSelection();
this._changeDetectorRef.markForCheck();
}
/** Clears the select trigger and deselects every option in the list. */