3
3
ComponentRef ,
4
4
ViewChild ,
5
5
ViewEncapsulation ,
6
- NgZone ,
7
- OnDestroy ,
8
6
Renderer ,
9
7
ElementRef ,
10
8
EventEmitter ,
@@ -21,11 +19,6 @@ import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} fr
21
19
import { MdDialogConfig } from './dialog-config' ;
22
20
import { MdDialogContentAlreadyAttachedError } from './dialog-errors' ;
23
21
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
22
30
23
31
24
/**
@@ -54,7 +47,7 @@ export type MdDialogContainerAnimationState = 'void' | 'enter' | 'exit' | 'exit-
54
47
'(@slideDialog.done)' : '_onAnimationDone($event)' ,
55
48
} ,
56
49
} )
57
- export class MdDialogContainer extends BasePortalHost implements OnDestroy {
50
+ export class MdDialogContainer extends BasePortalHost {
58
51
/** The portal host inside of this container into which the dialog content will be loaded. */
59
52
@ViewChild ( PortalHostDirective ) _portalHost : PortalHostDirective ;
60
53
@@ -68,13 +61,12 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
68
61
dialogConfig : MdDialogConfig ;
69
62
70
63
/** State of the dialog animation. */
71
- _state : MdDialogContainerAnimationState = 'enter' ;
64
+ _state : 'void' | 'enter' | 'exit' = 'enter' ;
72
65
73
66
/** Emits the current animation state whenever it changes. */
74
- _onAnimationStateChange = new EventEmitter < MdDialogContainerAnimationState > ( ) ;
67
+ _onAnimationStateChange = new EventEmitter < AnimationEvent > ( ) ;
75
68
76
69
constructor (
77
- private _ngZone : NgZone ,
78
70
private _renderer : Renderer ,
79
71
private _elementRef : ElementRef ,
80
72
private _focusTrapFactory : FocusTrapFactory ) {
@@ -108,7 +100,6 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
108
100
109
101
/**
110
102
* Moves the focus inside the focus trap.
111
- * @private
112
103
*/
113
104
private _trapFocus ( ) {
114
105
if ( ! this . _focusTrap ) {
@@ -122,47 +113,36 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
122
113
this . _focusTrap . focusFirstTabbableElementWhenReady ( ) ;
123
114
}
124
115
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
116
/**
135
117
* Callback, invoked whenever an animation on the host completes.
136
118
* @docs -private
137
119
*/
138
120
_onAnimationDone ( event : AnimationEvent ) {
121
+ this . _onAnimationStateChange . emit ( event ) ;
122
+
139
123
if ( event . toState === 'enter' ) {
140
124
this . _trapFocus ( ) ;
125
+ } else if ( event . toState === 'exit' ) {
126
+ this . _onAnimationStateChange . complete ( ) ;
141
127
}
142
-
143
- this . _onAnimationStateChange . emit ( event . toState as MdDialogContainerAnimationState ) ;
144
128
}
145
129
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
- }
130
+ /**
131
+ * Kicks off the leave animation and restores focus to the previously-focused element.
132
+ * @docs -private
133
+ */
134
+ _exit ( ) : void {
135
+ // We need the extra check, because IE can set the `activeElement` to null in some cases.
136
+ let toFocus = this . _elementFocusedBeforeDialogWasOpened ;
160
137
161
- animationStream . complete ( ) ;
162
- } ) ;
138
+ if ( toFocus && 'focus' in toFocus ) {
139
+ toFocus . focus ( ) ;
140
+ }
163
141
164
142
if ( this . _focusTrap ) {
165
143
this . _focusTrap . destroy ( ) ;
166
144
}
145
+
146
+ this . _state = 'exit' ;
167
147
}
168
148
}
0 commit comments