@@ -75,7 +75,15 @@ import {
75
75
} from '@angular/material/core' ;
76
76
import { MatFormField , MatFormFieldControl } from '@angular/material/form-field' ;
77
77
import { 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' ;
79
87
import { matSelectAnimations } from './select-animations' ;
80
88
import {
81
89
getMatSelectDynamicMultipleError ,
@@ -264,6 +272,9 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
264
272
/** Whether the panel's animation is done. */
265
273
_panelDoneAnimating : boolean = false ;
266
274
275
+ /** Emits when the panel element is finished transforming in. */
276
+ _panelDoneAnimatingStream = new Subject < string > ( ) ;
277
+
267
278
/** Strategy that will be used to handle scrolling while the select panel is open. */
268
279
_scrollStrategy = this . _scrollStrategyFactory ( ) ;
269
280
@@ -470,6 +481,23 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
470
481
ngOnInit ( ) {
471
482
this . _selectionModel = new SelectionModel < MatOption > ( this . multiple , undefined , false ) ;
472
483
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
+ } ) ;
473
501
}
474
502
475
503
ngAfterContentInit ( ) {
@@ -674,22 +702,6 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
674
702
}
675
703
}
676
704
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
-
693
705
/**
694
706
* When the panel content is done fading in, the _panelDoneAnimating property is
695
707
* set so the proper class can be added to the panel.
0 commit comments