mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
bug(autocomplete): deselect the other options when the user select an option (#3690)
* bug(autocomplete): deselect the other options when the user select one from the autocomplete Fixes #3689 * bug(autocomplete): only call deselect on the previous selected option. Unit tests.
This commit is contained in:
committed by
tinayuangao
parent
1ae81a4450
commit
61085633ef
@@ -307,6 +307,7 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
|
||||
*/
|
||||
private _setValueAndClose(event: MdOptionSelectionChange | null): void {
|
||||
if (event) {
|
||||
this._clearPreviousSelectedOption(event.source);
|
||||
this._setTriggerValue(event.source.value);
|
||||
this._onChange(event.source.value);
|
||||
}
|
||||
@@ -314,6 +315,17 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
|
||||
this.closePanel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any previous selected option and emit a selection change event for this option
|
||||
*/
|
||||
private _clearPreviousSelectedOption(skip: MdOption) {
|
||||
this.autocomplete.options.forEach((option) => {
|
||||
if (option != skip && option.selected) {
|
||||
option.deselect();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _createOverlay(): void {
|
||||
this._portal = new TemplatePortal(this.autocomplete.template, this._viewContainerRef);
|
||||
this._overlayRef = this._overlay.create(this._getOverlayConfig());
|
||||
|
||||
@@ -918,6 +918,69 @@ describe('MdAutocomplete', () => {
|
||||
|
||||
});
|
||||
|
||||
describe('Option selection', () => {
|
||||
let fixture: ComponentFixture<SimpleAutocomplete>;
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SimpleAutocomplete);
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.componentInstance.trigger.openPanel();
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should deselect any other selected option', async(() => {
|
||||
let options =
|
||||
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
|
||||
options[0].click();
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
|
||||
let componentOptions = fixture.componentInstance.options.toArray();
|
||||
expect(componentOptions[0].selected)
|
||||
.toBe(true, `Clicked option should be selected.`);
|
||||
|
||||
options =
|
||||
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
|
||||
options[1].click();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(componentOptions[0].selected)
|
||||
.toBe(false, `Previous option should not be selected.`);
|
||||
expect(componentOptions[1].selected)
|
||||
.toBe(true, `New Clicked option should be selected.`);
|
||||
|
||||
});
|
||||
}));
|
||||
|
||||
it('should call deselect only on the previous selected option', async(() => {
|
||||
let options =
|
||||
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
|
||||
options[0].click();
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
|
||||
let componentOptions = fixture.componentInstance.options.toArray();
|
||||
componentOptions.forEach(option => spyOn(option, 'deselect'));
|
||||
|
||||
expect(componentOptions[0].selected)
|
||||
.toBe(true, `Clicked option should be selected.`);
|
||||
|
||||
options =
|
||||
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
|
||||
options[1].click();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(componentOptions[0].deselect).toHaveBeenCalled();
|
||||
componentOptions.slice(1).forEach(option => expect(option.deselect).not.toHaveBeenCalled());
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('misc', () => {
|
||||
|
||||
it('should allow basic use without any forms directives', () => {
|
||||
|
||||
Reference in New Issue
Block a user