Skip to content

Commit

Permalink
fix(select): initial value not being displayed with FormControl and O…
Browse files Browse the repository at this point in the history
…nPush

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 angular#2269 (comment).
  • Loading branch information
crisbeto committed Mar 4, 2017
1 parent 94adecd commit bd00c7d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 20 deletions.
49 changes: 41 additions & 8 deletions src/lib/select/select.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ describe('MdSelect', () => {
FloatPlaceholderSelect,
SelectWithErrorSibling,
ThrowsErrorOnInit,
BasicSelectOnPush
BasicSelectOnPush,
BasicSelectOnPushPreselected
],
providers: [
{provide: OverlayContainer, useFactory: () => {
Expand Down Expand Up @@ -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();

Expand All @@ -1342,7 +1352,9 @@ describe('MdSelect', () => {

expect(trigger.textContent).not.toContain('Pizza');
});

});

});


Expand Down Expand Up @@ -1563,7 +1575,28 @@ class BasicSelectOnPush {
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');

@ViewChild(MdSelect) select: MdSelect;
}

@Component({
Expand Down
15 changes: 3 additions & 12 deletions src/lib/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,6 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
writeValue(value: any): void {
if (this.options) {
this._setSelectionByValue(value);
this._changeDetectorRef.markForCheck();
}
}

Expand Down Expand Up @@ -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. */
Expand Down

0 comments on commit bd00c7d

Please sign in to comment.