4
4
ViewChild ,
5
5
ViewEncapsulation ,
6
6
NgZone ,
7
- OnDestroy ,
8
7
Renderer ,
9
8
ElementRef ,
10
9
EventEmitter ,
@@ -21,11 +20,6 @@ import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} fr
21
20
import { MdDialogConfig } from './dialog-config' ;
22
21
import { MdDialogContentAlreadyAttachedError } from './dialog-errors' ;
23
22
import { FocusTrapFactory , FocusTrap } from '../core/a11y/focus-trap' ;
24
- import 'rxjs/add/operator/first' ;
25
-
26
-
27
- /** Possible states for the dialog container animation. */
28
- export type MdDialogContainerAnimationState = 'void' | 'enter' | 'exit' | 'exit-start' ;
29
23
30
24
31
25
/**
@@ -54,7 +48,7 @@ export type MdDialogContainerAnimationState = 'void' | 'enter' | 'exit' | 'exit-
54
48
'(@slideDialog.done)' : '_onAnimationDone($event)' ,
55
49
} ,
56
50
} )
57
- export class MdDialogContainer extends BasePortalHost implements OnDestroy {
51
+ export class MdDialogContainer extends BasePortalHost {
58
52
/** The portal host inside of this container into which the dialog content will be loaded. */
59
53
@ViewChild ( PortalHostDirective ) _portalHost : PortalHostDirective ;
60
54
@@ -68,13 +62,12 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
68
62
dialogConfig : MdDialogConfig ;
69
63
70
64
/** State of the dialog animation. */
71
- _state : MdDialogContainerAnimationState = 'enter' ;
65
+ _state : 'void' | 'enter' | 'exit' = 'enter' ;
72
66
73
67
/** Emits the current animation state whenever it changes. */
74
- _onAnimationStateChange = new EventEmitter < MdDialogContainerAnimationState > ( ) ;
68
+ _onAnimationStateChange = new EventEmitter < AnimationEvent > ( ) ;
75
69
76
70
constructor (
77
- private _ngZone : NgZone ,
78
71
private _renderer : Renderer ,
79
72
private _elementRef : ElementRef ,
80
73
private _focusTrapFactory : FocusTrapFactory ) {
@@ -108,7 +101,6 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
108
101
109
102
/**
110
103
* Moves the focus inside the focus trap.
111
- * @private
112
104
*/
113
105
private _trapFocus ( ) {
114
106
if ( ! this . _focusTrap ) {
@@ -122,47 +114,36 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
122
114
this . _focusTrap . focusFirstTabbableElementWhenReady ( ) ;
123
115
}
124
116
125
- /**
126
- * Kicks off the leave animation.
127
- * @docs -private
128
- */
129
- _exit ( ) : void {
130
- this . _state = 'exit' ;
131
- this . _onAnimationStateChange . emit ( 'exit-start' ) ;
132
- }
133
-
134
117
/**
135
118
* Callback, invoked whenever an animation on the host completes.
136
119
* @docs -private
137
120
*/
138
121
_onAnimationDone ( event : AnimationEvent ) {
122
+ this . _onAnimationStateChange . emit ( event ) ;
123
+
139
124
if ( event . toState === 'enter' ) {
140
125
this . _trapFocus ( ) ;
126
+ } else if ( event . toState === 'exit' ) {
127
+ this . _onAnimationStateChange . complete ( ) ;
141
128
}
142
-
143
- this . _onAnimationStateChange . emit ( event . toState as MdDialogContainerAnimationState ) ;
144
129
}
145
130
146
- ngOnDestroy ( ) {
147
- // When the dialog is destroyed, return focus to the element that originally had it before
148
- // the dialog was opened. Wait for the DOM to finish settling before changing the focus so
149
- // that it doesn't end up back on the <body>. Also note that we need the extra check, because
150
- // IE can set the `activeElement` to null in some cases.
151
- let toFocus = this . _elementFocusedBeforeDialogWasOpened as HTMLElement ;
152
-
153
- // We shouldn't use `this` inside of the NgZone subscription, because it causes a memory leak.
154
- let animationStream = this . _onAnimationStateChange ;
155
-
156
- this . _ngZone . onMicrotaskEmpty . first ( ) . subscribe ( ( ) => {
157
- if ( toFocus && 'focus' in toFocus ) {
158
- toFocus . focus ( ) ;
159
- }
131
+ /**
132
+ * Kicks off the leave animation and restores focus to the previously-focused element.
133
+ * @docs -private
134
+ */
135
+ _exit ( ) : void {
136
+ // We need the extra check, because IE can set the `activeElement` to null in some cases.
137
+ let toFocus = this . _elementFocusedBeforeDialogWasOpened ;
160
138
161
- animationStream . complete ( ) ;
162
- } ) ;
139
+ if ( toFocus && 'focus' in toFocus ) {
140
+ toFocus . focus ( ) ;
141
+ }
163
142
164
143
if ( this . _focusTrap ) {
165
144
this . _focusTrap . destroy ( ) ;
166
145
}
146
+
147
+ this . _state = 'exit' ;
167
148
}
168
149
}
0 commit comments