diff --git a/src/material/select/select.ts b/src/material/select/select.ts index 86600d535a6c..47856141a745 100644 --- a/src/material/select/select.ts +++ b/src/material/select/select.ts @@ -40,7 +40,6 @@ import { import {ViewportRuler} from '@angular/cdk/scrolling'; import { AfterContentInit, - AfterViewInit, Attribute, ChangeDetectionStrategy, ChangeDetectorRef, @@ -1283,7 +1282,7 @@ export class MatSelectTrigger {} {provide: MAT_OPTION_PARENT_COMPONENT, useExisting: MatSelect}, ], }) -export class MatSelect extends _MatSelectBase implements OnInit, AfterViewInit { +export class MatSelect extends _MatSelectBase implements OnInit { @ContentChildren(MatOption, {descendants: true}) options: QueryList; @ContentChildren(MAT_OPTGROUP, {descendants: true}) optionGroups: QueryList; @ContentChild(MAT_SELECT_TRIGGER) customTrigger: MatSelectTrigger; @@ -1332,23 +1331,23 @@ export class MatSelect extends _MatSelectBase implements OnInit .pipe(takeUntil(this._destroy)) .subscribe(() => { if (this.panelOpen) { - this._overlayWidth = this._getOverlayWidth(); + this._overlayWidth = this._getOverlayWidth(this._preferredOverlayOrigin); this._changeDetectorRef.detectChanges(); } }); } - ngAfterViewInit() { - // Note that it's important that we read this in `ngAfterViewInit`, because - // reading it earlier will cause the form field to return a different element. + override open() { + // It's important that we read this as late as possible, because doing so earlier will + // return a different element since it's based on queries in the form field which may + // not have run yet. Also this needs to be assigned before we measure the overlay width. if (this._parentFormField) { this._preferredOverlayOrigin = this._parentFormField.getConnectedOverlayOrigin(); } - } - override open() { - this._overlayWidth = this._getOverlayWidth(); + this._overlayWidth = this._getOverlayWidth(this._preferredOverlayOrigin); super.open(); + // Required for the MDC form field to pick up when the overlay has been opened. this.stateChanges.next(); } @@ -1393,12 +1392,14 @@ export class MatSelect extends _MatSelectBase implements OnInit } /** Gets how wide the overlay panel should be. */ - private _getOverlayWidth(): string | number { + private _getOverlayWidth( + preferredOrigin: ElementRef | CdkOverlayOrigin | undefined, + ): string | number { if (this.panelWidth === 'auto') { const refToMeasure = - this._preferredOverlayOrigin instanceof CdkOverlayOrigin - ? this._preferredOverlayOrigin.elementRef - : this._preferredOverlayOrigin || this._elementRef; + preferredOrigin instanceof CdkOverlayOrigin + ? preferredOrigin.elementRef + : preferredOrigin || this._elementRef; return refToMeasure.nativeElement.getBoundingClientRect().width; } diff --git a/tools/public_api_guard/material/select.md b/tools/public_api_guard/material/select.md index a9eb62796514..8d5837c95218 100644 --- a/tools/public_api_guard/material/select.md +++ b/tools/public_api_guard/material/select.md @@ -7,7 +7,6 @@ import { _AbstractConstructor } from '@angular/material/core'; import { ActiveDescendantKeyManager } from '@angular/cdk/a11y'; import { AfterContentInit } from '@angular/core'; -import { AfterViewInit } from '@angular/core'; import { AnimationTriggerMetadata } from '@angular/animations'; import { BooleanInput } from '@angular/cdk/coercion'; import { CanDisable } from '@angular/material/core'; @@ -76,7 +75,7 @@ export function MAT_SELECT_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay: Overlay): ( export const MAT_SELECT_TRIGGER: InjectionToken; // @public (undocumented) -export class MatSelect extends _MatSelectBase implements OnInit, AfterViewInit { +export class MatSelect extends _MatSelectBase implements OnInit { // (undocumented) close(): void; // (undocumented) @@ -86,8 +85,6 @@ export class MatSelect extends _MatSelectBase implements OnInit get hideSingleSelectionIndicator(): boolean; set hideSingleSelectionIndicator(value: BooleanInput); // (undocumented) - ngAfterViewInit(): void; - // (undocumented) ngOnInit(): void; // (undocumented) open(): void;