mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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:
committed by
vivian-hu
parent
4f755cf10c
commit
4913c36ea1
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
export * from './autocomplete';
|
||||
export * from './autocomplete-module';
|
||||
export * from './autocomplete-trigger';
|
||||
|
||||
export * from './autocomplete-origin';
|
||||
|
||||
Reference in New Issue
Block a user