fix(autocomplete): not updating origin if it changes after init (#14677)

* Fixes changes to the `matAutocompleteOrigin` input being ignored if they happen after the overlay has been initialized.
* Fixes the `MatAutocompleteOrigin` class not being exported as a part of the public API.
This commit is contained in:
Kristiyan Kostadinov
2019-01-16 19:38:48 +01:00
committed by vivian-hu
parent 4f755cf10c
commit 4913c36ea1
3 changed files with 48 additions and 11 deletions
+15 -9
View File
@@ -569,13 +569,16 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
throw getMatAutocompleteMissingPanelError();
}
if (!this._overlayRef) {
let overlayRef = this._overlayRef;
if (!overlayRef) {
this._portal = new TemplatePortal(this.autocomplete.template, this._viewContainerRef);
this._overlayRef = this._overlay.create(this._getOverlayConfig());
overlayRef = this._overlay.create(this._getOverlayConfig());
this._overlayRef = overlayRef;
// Use the `keydownEvents` in order to take advantage of
// the overlay event targeting provided by the CDK overlay.
this._overlayRef.keydownEvents().subscribe(event => {
overlayRef.keydownEvents().subscribe(event => {
// Close when pressing ESCAPE or ALT + UP_ARROW, based on the a11y guidelines.
// See: https://www.w3.org/TR/wai-aria-practices-1.1/#textbox-keyboard-interaction
if (event.keyCode === ESCAPE || (event.keyCode === UP_ARROW && event.altKey)) {
@@ -586,18 +589,21 @@ export class MatAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
if (this._viewportRuler) {
this._viewportSubscription = this._viewportRuler.change().subscribe(() => {
if (this.panelOpen && this._overlayRef) {
this._overlayRef.updateSize({width: this._getPanelWidth()});
if (this.panelOpen && overlayRef) {
overlayRef.updateSize({width: this._getPanelWidth()});
}
});
}
} else {
// Update the panel width and direction, in case anything has changed.
this._overlayRef.updateSize({width: this._getPanelWidth()});
const position = overlayRef.getConfig().positionStrategy as FlexibleConnectedPositionStrategy;
// Update the trigger, panel width and direction, in case anything has changed.
position.setOrigin(this._getConnectedElement());
overlayRef.updateSize({width: this._getPanelWidth()});
}
if (this._overlayRef && !this._overlayRef.hasAttached()) {
this._overlayRef.attach(this._portal);
if (overlayRef && !overlayRef.hasAttached()) {
overlayRef.attach(this._portal);
this._closingActionsSubscription = this._subscribeToClosingActions();
}
+32 -1
View File
@@ -47,6 +47,7 @@ import {
MatAutocompleteModule,
MatAutocompleteSelectedEvent,
MatAutocompleteTrigger,
MatAutocompleteOrigin,
} from './index';
@@ -2218,6 +2219,34 @@ describe('MatAutocomplete', () => {
const fixture = createComponent(AutocompleteWithDifferentOrigin);
fixture.detectChanges();
fixture.componentInstance.connectedTo = fixture.componentInstance.alternateOrigin;
fixture.detectChanges();
fixture.componentInstance.trigger.openPanel();
fixture.detectChanges();
zone.simulateZoneExit();
const overlayRect =
overlayContainerElement.querySelector('.cdk-overlay-pane')!.getBoundingClientRect();
const originRect = fixture.nativeElement.querySelector('.origin').getBoundingClientRect();
expect(Math.floor(overlayRect.top)).toBe(Math.floor(originRect.bottom),
'Expected autocomplete panel to align with the bottom of the new origin.');
});
it('should be able to change the origin after the panel has been opened', () => {
const fixture = createComponent(AutocompleteWithDifferentOrigin);
fixture.detectChanges();
fixture.componentInstance.trigger.openPanel();
fixture.detectChanges();
zone.simulateZoneExit();
fixture.componentInstance.trigger.closePanel();
fixture.detectChanges();
fixture.componentInstance.connectedTo = fixture.componentInstance.alternateOrigin;
fixture.detectChanges();
fixture.componentInstance.trigger.openPanel();
fixture.detectChanges();
zone.simulateZoneExit();
@@ -2603,7 +2632,7 @@ class AutocompleteWithNumberInputAndNgModel {
<input
matInput
[matAutocomplete]="auto"
[matAutocompleteConnectedTo]="origin"
[matAutocompleteConnectedTo]="connectedTo"
[(ngModel)]="selectedValue">
</mat-form-field>
</div>
@@ -2623,8 +2652,10 @@ class AutocompleteWithNumberInputAndNgModel {
})
class AutocompleteWithDifferentOrigin {
@ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
@ViewChild(MatAutocompleteOrigin) alternateOrigin: MatAutocompleteOrigin;
selectedValue: string;
values = ['one', 'two', 'three'];
connectedTo?: MatAutocompleteOrigin;
}
@Component({
+1 -1
View File
@@ -9,4 +9,4 @@
export * from './autocomplete';
export * from './autocomplete-module';
export * from './autocomplete-trigger';
export * from './autocomplete-origin';