@@ -75,7 +75,15 @@ import {
7575} from '@angular/material/core' ;
7676import { MatFormField , MatFormFieldControl } from '@angular/material/form-field' ;
7777import { defer , merge , Observable , Subject } from 'rxjs' ;
78- import { filter , map , startWith , switchMap , take , takeUntil } from 'rxjs/operators' ;
78+ import {
79+ filter ,
80+ map ,
81+ startWith ,
82+ switchMap ,
83+ take ,
84+ takeUntil ,
85+ distinctUntilChanged ,
86+ } from 'rxjs/operators' ;
7987import { matSelectAnimations } from './select-animations' ;
8088import {
8189 getMatSelectDynamicMultipleError ,
@@ -264,6 +272,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
264272 /** Whether the panel's animation is done. */
265273 _panelDoneAnimating : boolean = false ;
266274
275+ /** Emits when the panel element is finished transforming in. */
276+ _panelDoneAnimatingStream = new Subject < string > ( ) ;
277+
267278 /** Strategy that will be used to handle scrolling while the select panel is open. */
268279 _scrollStrategy = this . _scrollStrategyFactory ( ) ;
269280
@@ -470,6 +481,23 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
470481 ngOnInit ( ) {
471482 this . _selectionModel = new SelectionModel < MatOption > ( this . multiple , undefined , false ) ;
472483 this . stateChanges . next ( ) ;
484+
485+ // We need `distinctUntilChanged` here, because some browsers will
486+ // fire the animation end event twice for the same animation. See:
487+ // https://github.com/angular/angular/issues/24084
488+ this . _panelDoneAnimatingStream
489+ . pipe ( distinctUntilChanged ( ) , takeUntil ( this . _destroy ) )
490+ . subscribe ( ( ) => {
491+ if ( this . panelOpen ) {
492+ this . _scrollTop = 0 ;
493+ this . openedChange . emit ( true ) ;
494+ } else {
495+ this . openedChange . emit ( false ) ;
496+ this . _panelDoneAnimating = false ;
497+ this . overlayDir . offsetX = 0 ;
498+ this . _changeDetectorRef . markForCheck ( ) ;
499+ }
500+ } ) ;
473501 }
474502
475503 ngAfterContentInit ( ) {
@@ -674,22 +702,6 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
674702 }
675703 }
676704
677- /**
678- * When the panel element is finished transforming in (though not fading in), it
679- * emits an event and focuses an option if the panel is open.
680- */
681- _onPanelDone ( ) : void {
682- if ( this . panelOpen ) {
683- this . _scrollTop = 0 ;
684- this . openedChange . emit ( true ) ;
685- } else {
686- this . openedChange . emit ( false ) ;
687- this . _panelDoneAnimating = false ;
688- this . overlayDir . offsetX = 0 ;
689- this . _changeDetectorRef . markForCheck ( ) ;
690- }
691- }
692-
693705 /**
694706 * When the panel content is done fading in, the _panelDoneAnimating property is
695707 * set so the proper class can be added to the panel.
0 commit comments