mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(select): selected option not being highlighted when options are added asynchronously (#2499)
* fix(select): selected option not being highlighted when options are added asynchronously Fixes the select component not highlighting the model value when the options get added after initialization. Fixes #2497. * Address the feedback. * Fix linter errors.
This commit is contained in:
committed by
tinayuangao
parent
6f94aa1140
commit
7fc38b9bdd
@@ -16,7 +16,14 @@ describe('MdSelect', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [MdSelectModule.forRoot(), ReactiveFormsModule, FormsModule],
|
||||
declarations: [BasicSelect, NgModelSelect, ManySelects, NgIfSelect, SelectWithChangeEvent],
|
||||
declarations: [
|
||||
BasicSelect,
|
||||
NgModelSelect,
|
||||
ManySelects,
|
||||
NgIfSelect,
|
||||
SelectInitWithoutOptions,
|
||||
SelectWithChangeEvent
|
||||
],
|
||||
providers: [
|
||||
{provide: OverlayContainer, useFactory: () => {
|
||||
overlayContainerElement = document.createElement('div') as HTMLElement;
|
||||
@@ -239,6 +246,27 @@ describe('MdSelect', () => {
|
||||
|
||||
});
|
||||
|
||||
it('should select the proper option when the list of options is initialized at a later point',
|
||||
async(() => {
|
||||
let fixture = TestBed.createComponent(SelectInitWithoutOptions);
|
||||
let instance = fixture.componentInstance;
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
// Wait for the initial writeValue promise.
|
||||
fixture.whenStable().then(() => {
|
||||
expect(instance.select.selected).toBeFalsy();
|
||||
|
||||
instance.addOptions();
|
||||
fixture.detectChanges();
|
||||
|
||||
// Wait for the next writeValue promise.
|
||||
fixture.whenStable().then(() => {
|
||||
expect(instance.select.selected).toBe(instance.options.toArray()[1]);
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
describe('forms integration', () => {
|
||||
let fixture: ComponentFixture<BasicSelect>;
|
||||
let trigger: HTMLElement;
|
||||
@@ -1267,7 +1295,6 @@ class ManySelects {}
|
||||
</md-select>
|
||||
</div>
|
||||
`,
|
||||
|
||||
})
|
||||
class NgIfSelect {
|
||||
isShowing = false;
|
||||
@@ -1304,6 +1331,32 @@ class SelectWithChangeEvent {
|
||||
changeListener = jasmine.createSpy('MdSelect change listener');
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'select-init-without-options',
|
||||
template: `
|
||||
<md-select placeholder="Food I want to eat right now" [formControl]="control">
|
||||
<md-option *ngFor="let food of foods" [value]="food.value">
|
||||
{{ food.viewValue }}
|
||||
</md-option>
|
||||
</md-select>
|
||||
`
|
||||
})
|
||||
class SelectInitWithoutOptions {
|
||||
foods: any[];
|
||||
control = new FormControl('pizza-1');
|
||||
|
||||
@ViewChild(MdSelect) select: MdSelect;
|
||||
@ViewChildren(MdOption) options: QueryList<MdOption>;
|
||||
|
||||
addOptions() {
|
||||
this.foods = [
|
||||
{ value: 'steak-0', viewValue: 'Steak' },
|
||||
{ value: 'pizza-1', viewValue: 'Pizza' },
|
||||
{ value: 'tacos-2', viewValue: 'Tacos'}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Move this to core testing utility until Angular has event faking
|
||||
* support.
|
||||
|
||||
@@ -241,7 +241,15 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
|
||||
ngAfterContentInit() {
|
||||
this._initKeyManager();
|
||||
this._resetOptions();
|
||||
this._changeSubscription = this.options.changes.subscribe(() => this._resetOptions());
|
||||
this._changeSubscription = this.options.changes.subscribe(() => {
|
||||
this._resetOptions();
|
||||
|
||||
if (this._control) {
|
||||
// Defer setting the value in order to avoid the "Expression
|
||||
// has changed after it was checked" errors from Angular.
|
||||
Promise.resolve(null).then(() => this._setSelectionByValue(this._control.value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
||||
Reference in New Issue
Block a user