44 ViewChild ,
55 ViewEncapsulation ,
66 NgZone ,
7- OnDestroy ,
87 Renderer ,
98 ElementRef ,
109 EventEmitter ,
@@ -21,11 +20,6 @@ import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} fr
2120import { MdDialogConfig } from './dialog-config' ;
2221import { MdDialogContentAlreadyAttachedError } from './dialog-errors' ;
2322import { 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' ;
2923
3024
3125/**
@@ -54,7 +48,7 @@ export type MdDialogContainerAnimationState = 'void' | 'enter' | 'exit' | 'exit-
5448 '(@slideDialog.done)' : '_onAnimationDone($event)' ,
5549 } ,
5650} )
57- export class MdDialogContainer extends BasePortalHost implements OnDestroy {
51+ export class MdDialogContainer extends BasePortalHost {
5852 /** The portal host inside of this container into which the dialog content will be loaded. */
5953 @ViewChild ( PortalHostDirective ) _portalHost : PortalHostDirective ;
6054
@@ -68,13 +62,12 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
6862 dialogConfig : MdDialogConfig ;
6963
7064 /** State of the dialog animation. */
71- _state : MdDialogContainerAnimationState = 'enter' ;
65+ _state : 'void' | 'enter' | 'exit' = 'enter' ;
7266
7367 /** Emits the current animation state whenever it changes. */
74- _onAnimationStateChange = new EventEmitter < MdDialogContainerAnimationState > ( ) ;
68+ _onAnimationStateChange = new EventEmitter < AnimationEvent > ( ) ;
7569
7670 constructor (
77- private _ngZone : NgZone ,
7871 private _renderer : Renderer ,
7972 private _elementRef : ElementRef ,
8073 private _focusTrapFactory : FocusTrapFactory ) {
@@ -108,7 +101,6 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
108101
109102 /**
110103 * Moves the focus inside the focus trap.
111- * @private
112104 */
113105 private _trapFocus ( ) {
114106 if ( ! this . _focusTrap ) {
@@ -122,47 +114,36 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
122114 this . _focusTrap . focusFirstTabbableElementWhenReady ( ) ;
123115 }
124116
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-
134117 /**
135118 * Callback, invoked whenever an animation on the host completes.
136119 * @docs -private
137120 */
138121 _onAnimationDone ( event : AnimationEvent ) {
122+ this . _onAnimationStateChange . emit ( event ) ;
123+
139124 if ( event . toState === 'enter' ) {
140125 this . _trapFocus ( ) ;
126+ } else if ( event . toState === 'exit' ) {
127+ this . _onAnimationStateChange . complete ( ) ;
141128 }
142-
143- this . _onAnimationStateChange . emit ( event . toState as MdDialogContainerAnimationState ) ;
144129 }
145130
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 ;
160138
161- animationStream . complete ( ) ;
162- } ) ;
139+ if ( toFocus && 'focus' in toFocus ) {
140+ toFocus . focus ( ) ;
141+ }
163142
164143 if ( this . _focusTrap ) {
165144 this . _focusTrap . destroy ( ) ;
166145 }
146+
147+ this . _state = 'exit' ;
167148 }
168149}
0 commit comments