@@ -23,6 +23,7 @@ import {
2323 HorizontalConnectionPos ,
2424 VerticalConnectionPos
2525} from '../core' ;
26+ import { Subscription } from 'rxjs/Subscription' ;
2627
2728/**
2829 * This directive is intended to be used in conjunction with an md-menu tag. It is
@@ -40,6 +41,7 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
4041 private _portal : TemplatePortal ;
4142 private _overlayRef : OverlayRef ;
4243 private _menuOpen : boolean = false ;
44+ private _backdropSubscription : Subscription ;
4345
4446 // tracking input type is necessary so it's possible to only auto-focus
4547 // the first item of the list when the menu is opened via the keyboard
@@ -70,13 +72,15 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
7072 if ( ! this . _menuOpen ) {
7173 this . _createOverlay ( ) ;
7274 this . _overlayRef . attach ( this . _portal ) ;
75+ this . _subscribeToBackdrop ( ) ;
7376 this . _initMenu ( ) ;
7477 }
7578 }
7679
7780 closeMenu ( ) : void {
7881 if ( this . _overlayRef ) {
7982 this . _overlayRef . detach ( ) ;
83+ this . _backdropSubscription . unsubscribe ( ) ;
8084 this . _resetMenu ( ) ;
8185 }
8286 }
@@ -85,13 +89,29 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
8589 if ( this . _overlayRef ) {
8690 this . _overlayRef . dispose ( ) ;
8791 this . _overlayRef = null ;
92+
93+ if ( this . _backdropSubscription ) {
94+ this . _backdropSubscription . unsubscribe ( ) ;
95+ }
8896 }
8997 }
9098
9199 focus ( ) {
92100 this . _renderer . invokeElementMethod ( this . _element . nativeElement , 'focus' ) ;
93101 }
94102
103+ /**
104+ * This method ensures that the menu closes when the overlay backdrop is clicked.
105+ * We do not use first() here because doing so would not catch clicks from within
106+ * the menu, and it would fail to unsubscribe properly. Instead, we unsubscribe
107+ * explicitly when the menu is closed or destroyed.
108+ */
109+ private _subscribeToBackdrop ( ) : void {
110+ this . _backdropSubscription = this . _overlayRef . backdropClick ( ) . subscribe ( ( ) => {
111+ this . closeMenu ( ) ;
112+ } ) ;
113+ }
114+
95115 /**
96116 * This method sets the menu state to open and focuses the first item if
97117 * the menu was opened via the keyboard.
@@ -120,7 +140,6 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
120140 // set state rather than toggle to support triggers sharing a menu
121141 private _setIsMenuOpen ( isOpen : boolean ) : void {
122142 this . _menuOpen = isOpen ;
123- this . menu . _setClickCatcher ( isOpen ) ;
124143 this . _menuOpen ? this . onMenuOpen . emit ( null ) : this . onMenuClose . emit ( null ) ;
125144 }
126145
@@ -152,6 +171,8 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
152171 private _getOverlayConfig ( ) : OverlayState {
153172 const overlayState = new OverlayState ( ) ;
154173 overlayState . positionStrategy = this . _getPosition ( ) ;
174+ overlayState . hasBackdrop = true ;
175+ overlayState . backdropClass = 'md-overlay-transparent-backdrop' ;
155176 return overlayState ;
156177 }
157178
0 commit comments