@@ -30,11 +30,12 @@ import {
30
30
TemplateRef ,
31
31
Type ,
32
32
} from '@angular/core' ;
33
- import { defer , Observable , of as observableOf , Subject } from 'rxjs' ;
33
+ import { defer , Observable , of as observableOf , Subject , Subscription } from 'rxjs' ;
34
34
import { startWith } from 'rxjs/operators' ;
35
35
import { MatDialogConfig } from './dialog-config' ;
36
36
import { MatDialogContainer , _MatDialogContainerBase } from './dialog-container' ;
37
37
import { MatDialogRef } from './dialog-ref' ;
38
+ import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations' ;
38
39
39
40
40
41
/** Injection token that can be used to access the data that was passed in to a dialog. */
@@ -77,6 +78,9 @@ export abstract class _MatDialogBase<C extends _MatDialogContainerBase> implemen
77
78
private readonly _afterOpenedAtThisLevel = new Subject < MatDialogRef < any > > ( ) ;
78
79
private _ariaHiddenElements = new Map < Element , string | null > ( ) ;
79
80
private _scrollStrategy : ( ) => ScrollStrategy ;
81
+ private _dialogAnimatingOpen = false ;
82
+ private _animationStateSubscriptions : Subscription ;
83
+ private _lastDialogRef : MatDialogRef < any > ;
80
84
81
85
/** Keeps track of the currently-open dialogs. */
82
86
get openDialogs ( ) : MatDialogRef < any > [ ] {
@@ -111,7 +115,8 @@ export abstract class _MatDialogBase<C extends _MatDialogContainerBase> implemen
111
115
scrollStrategy : any ,
112
116
private _dialogRefConstructor : Type < MatDialogRef < any > > ,
113
117
private _dialogContainerType : Type < C > ,
114
- private _dialogDataToken : InjectionToken < any > ) {
118
+ private _dialogDataToken : InjectionToken < any > ,
119
+ private _animationMode ?: 'NoopAnimations' | 'BrowserAnimations' ) {
115
120
this . _scrollStrategy = scrollStrategy ;
116
121
}
117
122
@@ -145,12 +150,35 @@ export abstract class _MatDialogBase<C extends _MatDialogContainerBase> implemen
145
150
throw Error ( `Dialog with id "${ config . id } " exists already. The dialog id must be unique.` ) ;
146
151
}
147
152
153
+ // If there is a dialog that is currently animating open, return the MatDialogRef of that dialog
154
+ if ( this . _dialogAnimatingOpen ) {
155
+ return this . _lastDialogRef ;
156
+ }
157
+
148
158
const overlayRef = this . _createOverlay ( config ) ;
149
159
const dialogContainer = this . _attachDialogContainer ( overlayRef , config ) ;
160
+ if ( this . _animationMode !== 'NoopAnimations' ) {
161
+ const animationStateSubscription =
162
+ dialogContainer . _animationStateChanged . subscribe ( ( dialogAnimationEvent ) => {
163
+ if ( dialogAnimationEvent . state === 'opening' ) {
164
+ this . _dialogAnimatingOpen = true ;
165
+ }
166
+ if ( dialogAnimationEvent . state === 'opened' ) {
167
+ this . _dialogAnimatingOpen = false ;
168
+ animationStateSubscription . unsubscribe ( ) ;
169
+ }
170
+ } ) ;
171
+ if ( ! this . _animationStateSubscriptions ) {
172
+ this . _animationStateSubscriptions = new Subscription ( ) ;
173
+ }
174
+ this . _animationStateSubscriptions . add ( animationStateSubscription ) ;
175
+ }
176
+
150
177
const dialogRef = this . _attachDialogContent < T , R > ( componentOrTemplateRef ,
151
178
dialogContainer ,
152
179
overlayRef ,
153
180
config ) ;
181
+ this . _lastDialogRef = dialogRef ;
154
182
155
183
// If this is the first dialog that we're opening, hide all the non-overlay content.
156
184
if ( ! this . openDialogs . length ) {
@@ -188,6 +216,10 @@ export abstract class _MatDialogBase<C extends _MatDialogContainerBase> implemen
188
216
this . _closeDialogs ( this . _openDialogsAtThisLevel ) ;
189
217
this . _afterAllClosedAtThisLevel . complete ( ) ;
190
218
this . _afterOpenedAtThisLevel . complete ( ) ;
219
+ // Clean up any subscriptions to dialogs that never finished opening.
220
+ if ( this . _animationStateSubscriptions ) {
221
+ this . _animationStateSubscriptions . unsubscribe ( ) ;
222
+ }
191
223
}
192
224
193
225
/**
@@ -392,19 +424,19 @@ export abstract class _MatDialogBase<C extends _MatDialogContainerBase> implemen
392
424
@Injectable ( )
393
425
export class MatDialog extends _MatDialogBase < MatDialogContainer > {
394
426
constructor (
395
- overlay : Overlay ,
396
- injector : Injector ,
427
+ overlay : Overlay , injector : Injector ,
397
428
/**
398
429
* @deprecated `_location` parameter to be removed.
399
430
* @breaking -change 10.0.0
400
431
*/
401
432
@Optional ( ) location : Location ,
402
433
@Optional ( ) @Inject ( MAT_DIALOG_DEFAULT_OPTIONS ) defaultOptions : MatDialogConfig ,
403
434
@Inject ( MAT_DIALOG_SCROLL_STRATEGY ) scrollStrategy : any ,
404
- @Optional ( ) @SkipSelf ( ) parentDialog : MatDialog ,
405
- overlayContainer : OverlayContainer ) {
435
+ @Optional ( ) @SkipSelf ( ) parentDialog : MatDialog , overlayContainer : OverlayContainer ,
436
+ @Optional ( ) @Inject ( ANIMATION_MODULE_TYPE ) animationMode ?: 'NoopAnimations' |
437
+ 'BrowserAnimations' ) {
406
438
super ( overlay , injector , defaultOptions , parentDialog , overlayContainer , scrollStrategy ,
407
- MatDialogRef , MatDialogContainer , MAT_DIALOG_DATA ) ;
439
+ MatDialogRef , MatDialogContainer , MAT_DIALOG_DATA , animationMode ) ;
408
440
}
409
441
}
410
442
0 commit comments