33 ComponentRef ,
44 ViewChild ,
55 ViewEncapsulation ,
6- NgZone ,
7- OnDestroy ,
86 Renderer ,
97 ElementRef ,
108 EventEmitter ,
@@ -21,11 +19,6 @@ import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} fr
2119import { MdDialogConfig } from './dialog-config' ;
2220import { MdDialogContentAlreadyAttachedError } from './dialog-errors' ;
2321import { 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' ;
2922
3023
3124/**
@@ -54,7 +47,7 @@ export type MdDialogContainerAnimationState = 'void' | 'enter' | 'exit' | 'exit-
5447 '(@slideDialog.done)' : '_onAnimationDone($event)' ,
5548 } ,
5649} )
57- export class MdDialogContainer extends BasePortalHost implements OnDestroy {
50+ export class MdDialogContainer extends BasePortalHost {
5851 /** The portal host inside of this container into which the dialog content will be loaded. */
5952 @ViewChild ( PortalHostDirective ) _portalHost : PortalHostDirective ;
6053
@@ -68,13 +61,12 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
6861 dialogConfig : MdDialogConfig ;
6962
7063 /** State of the dialog animation. */
71- _state : MdDialogContainerAnimationState = 'enter' ;
64+ _state : 'void' | 'enter' | 'exit' = 'enter' ;
7265
7366 /** Emits the current animation state whenever it changes. */
74- _onAnimationStateChange = new EventEmitter < MdDialogContainerAnimationState > ( ) ;
67+ _onAnimationStateChange = new EventEmitter < AnimationEvent > ( ) ;
7568
7669 constructor (
77- private _ngZone : NgZone ,
7870 private _renderer : Renderer ,
7971 private _elementRef : ElementRef ,
8072 private _focusTrapFactory : FocusTrapFactory ) {
@@ -108,7 +100,6 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
108100
109101 /**
110102 * Moves the focus inside the focus trap.
111- * @private
112103 */
113104 private _trapFocus ( ) {
114105 if ( ! this . _focusTrap ) {
@@ -122,47 +113,36 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
122113 this . _focusTrap . focusFirstTabbableElementWhenReady ( ) ;
123114 }
124115
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-
134116 /**
135117 * Callback, invoked whenever an animation on the host completes.
136118 * @docs -private
137119 */
138120 _onAnimationDone ( event : AnimationEvent ) {
121+ this . _onAnimationStateChange . emit ( event ) ;
122+
139123 if ( event . toState === 'enter' ) {
140124 this . _trapFocus ( ) ;
125+ } else if ( event . toState === 'exit' ) {
126+ this . _onAnimationStateChange . complete ( ) ;
141127 }
142-
143- this . _onAnimationStateChange . emit ( event . toState as MdDialogContainerAnimationState ) ;
144128 }
145129
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 ;
160137
161- animationStream . complete ( ) ;
162- } ) ;
138+ if ( toFocus && 'focus' in toFocus ) {
139+ toFocus . focus ( ) ;
140+ }
163141
164142 if ( this . _focusTrap ) {
165143 this . _focusTrap . destroy ( ) ;
166144 }
145+
146+ this . _state = 'exit' ;
167147 }
168148}
0 commit comments