@@ -34,7 +34,7 @@ import {
34
34
ViewContainerRef ,
35
35
} from '@angular/core' ;
36
36
import { normalizePassiveListenerOptions } from '@angular/cdk/platform' ;
37
- import { asapScheduler , merge , of as observableOf , Subscription } from 'rxjs' ;
37
+ import { asapScheduler , merge , of as observableOf , Subscription , Subject } from 'rxjs' ;
38
38
import { delay , filter , take , takeUntil } from 'rxjs/operators' ;
39
39
import { MatMenu } from './menu-directive' ;
40
40
import { throwMatMenuMissingError } from './menu-errors' ;
@@ -85,8 +85,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
85
85
private _portal : TemplatePortal ;
86
86
private _overlayRef : OverlayRef | null = null ;
87
87
private _menuOpen : boolean = false ;
88
- private _closeSubscription = Subscription . EMPTY ;
89
- private _hoverSubscription = Subscription . EMPTY ;
88
+ private _destroyed = new Subject ( ) ;
90
89
private _menuCloseSubscription = Subscription . EMPTY ;
91
90
private _scrollStrategy : ( ) => ScrollStrategy ;
92
91
@@ -194,7 +193,9 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
194
193
this . _element . nativeElement . removeEventListener ( 'touchstart' , this . _handleTouchStart ,
195
194
passiveEventListenerOptions ) ;
196
195
197
- this . _cleanUpSubscriptions ( ) ;
196
+ this . _menuCloseSubscription . unsubscribe ( ) ;
197
+ this . _destroyed . next ( ) ;
198
+ this . _destroyed . complete ( ) ;
198
199
}
199
200
200
201
/** Whether the menu is open. */
@@ -233,7 +234,9 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
233
234
this . menu . lazyContent . attach ( this . menuData ) ;
234
235
}
235
236
236
- this . _closeSubscription = this . _menuClosingActions ( ) . subscribe ( ( ) => this . closeMenu ( ) ) ;
237
+ this . _menuClosingActions ( )
238
+ . pipe ( takeUntil ( merge ( this . _destroyed , overlayRef . detachments ( ) ) ) )
239
+ . subscribe ( ( ) => this . closeMenu ( ) ) ;
237
240
this . _initMenu ( ) ;
238
241
239
242
if ( this . menu instanceof MatMenu ) {
@@ -266,7 +269,6 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
266
269
267
270
const menu = this . menu ;
268
271
269
- this . _closeSubscription . unsubscribe ( ) ;
270
272
this . _overlayRef . detach ( ) ;
271
273
272
274
if ( menu instanceof MatMenu ) {
@@ -464,12 +466,6 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
464
466
] ) ;
465
467
}
466
468
467
- /** Cleans up the active subscriptions. */
468
- private _cleanUpSubscriptions ( ) : void {
469
- this . _closeSubscription . unsubscribe ( ) ;
470
- this . _hoverSubscription . unsubscribe ( ) ;
471
- }
472
-
473
469
/** Returns a stream that emits whenever an action that should close the menu occurs. */
474
470
private _menuClosingActions ( ) {
475
471
const backdrop = this . _overlayRef ! . backdropClick ( ) ;
@@ -528,13 +524,14 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
528
524
return ;
529
525
}
530
526
531
- this . _hoverSubscription = this . _parentMenu . _hovered ( )
527
+ this . _parentMenu . _hovered ( )
532
528
// Since we might have multiple competing triggers for the same menu (e.g. a sub-menu
533
529
// with different data and triggers), we have to delay it by a tick to ensure that
534
530
// it won't be closed immediately after it is opened.
535
531
. pipe (
536
532
filter ( active => active === this . _menuItemInstance && ! active . disabled ) ,
537
- delay ( 0 , asapScheduler )
533
+ delay ( 0 , asapScheduler ) ,
534
+ takeUntil ( this . _destroyed )
538
535
)
539
536
. subscribe ( ( ) => {
540
537
this . _openedBy = 'mouse' ;
0 commit comments