@@ -84,6 +84,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
84
84
private _menuOpen : boolean = false ;
85
85
private _closeSubscription = Subscription . EMPTY ;
86
86
private _hoverSubscription = Subscription . EMPTY ;
87
+ private _menuCloseSubscription = Subscription . EMPTY ;
87
88
private _scrollStrategy : ( ) => ScrollStrategy ;
88
89
89
90
// Tracking input type is necessary so it's possible to only auto-focus
@@ -95,16 +96,31 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
95
96
* @breaking -change 8.0.0
96
97
*/
97
98
@Input ( 'mat-menu-trigger-for' )
98
- get _deprecatedMatMenuTriggerFor ( ) : MatMenuPanel {
99
- return this . menu ;
100
- }
101
-
99
+ get _deprecatedMatMenuTriggerFor ( ) : MatMenuPanel { return this . menu ; }
102
100
set _deprecatedMatMenuTriggerFor ( v : MatMenuPanel ) {
103
101
this . menu = v ;
104
102
}
105
103
106
104
/** References the menu instance that the trigger is associated with. */
107
- @Input ( 'matMenuTriggerFor' ) menu : MatMenuPanel ;
105
+ @Input ( 'matMenuTriggerFor' )
106
+ get menu ( ) { return this . _menu ; }
107
+ set menu ( menu : MatMenuPanel ) {
108
+ if ( ! menu || menu === this . _menu ) {
109
+ return ;
110
+ }
111
+
112
+ this . _menu = menu ;
113
+ this . _menuCloseSubscription . unsubscribe ( ) ;
114
+ this . _menuCloseSubscription = menu . close . asObservable ( ) . subscribe ( reason => {
115
+ this . _destroyMenu ( ) ;
116
+
117
+ // If a click closed the menu, we should close the entire chain of nested menus.
118
+ if ( ( reason === 'click' || reason === 'tab' ) && this . _parentMenu ) {
119
+ this . _parentMenu . closed . emit ( reason ) ;
120
+ }
121
+ } ) ;
122
+ }
123
+ private _menu : MatMenuPanel ;
108
124
109
125
/** Data to be passed along to any lazily-rendered content. */
110
126
@Input ( 'matMenuTriggerData' ) menuData : any ;
@@ -151,16 +167,6 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
151
167
152
168
ngAfterContentInit ( ) {
153
169
this . _checkMenu ( ) ;
154
-
155
- this . menu . close . asObservable ( ) . subscribe ( reason => {
156
- this . _destroyMenu ( ) ;
157
-
158
- // If a click closed the menu, we should close the entire chain of nested menus.
159
- if ( ( reason === 'click' || reason === 'tab' ) && this . _parentMenu ) {
160
- this . _parentMenu . closed . emit ( reason ) ;
161
- }
162
- } ) ;
163
-
164
170
this . _handleHover ( ) ;
165
171
}
166
172
@@ -203,7 +209,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
203
209
204
210
const overlayRef = this . _createOverlay ( ) ;
205
211
this . _setPosition ( overlayRef . getConfig ( ) . positionStrategy as FlexibleConnectedPositionStrategy ) ;
206
- overlayRef . attach ( this . _portal ) ;
212
+ overlayRef . attach ( this . _getPortal ( ) ) ;
207
213
208
214
if ( this . menu . lazyContent ) {
209
215
this . menu . lazyContent . attach ( this . menuData ) ;
@@ -347,7 +353,6 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
347
353
*/
348
354
private _createOverlay ( ) : OverlayRef {
349
355
if ( ! this . _overlayRef ) {
350
- this . _portal = new TemplatePortal ( this . menu . templateRef , this . _viewContainerRef ) ;
351
356
const config = this . _getOverlayConfig ( ) ;
352
357
this . _subscribeToPositions ( config . positionStrategy as FlexibleConnectedPositionStrategy ) ;
353
358
this . _overlayRef = this . _overlay . create ( config ) ;
@@ -531,4 +536,16 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
531
536
} ) ;
532
537
}
533
538
539
+ /** Gets the portal that should be attached to the overlay. */
540
+ private _getPortal ( ) : TemplatePortal {
541
+ // Note that we can avoid this check by keeping the portal on the menu panel.
542
+ // While it would be cleaner, we'd have to introduce another required method on
543
+ // `MatMenuPanel`, making it harder to consume.
544
+ if ( ! this . _portal || this . _portal . templateRef !== this . menu . templateRef ) {
545
+ this . _portal = new TemplatePortal ( this . menu . templateRef , this . _viewContainerRef ) ;
546
+ }
547
+
548
+ return this . _portal ;
549
+ }
550
+
534
551
}
0 commit comments