@@ -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,34 @@ 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 === this . _menu ) {
109
+ return ;
110
+ }
111
+
112
+ this . _menu = menu ;
113
+ this . _menuCloseSubscription . unsubscribe ( ) ;
114
+
115
+ if ( menu ) {
116
+ this . _menuCloseSubscription = menu . close . asObservable ( ) . subscribe ( reason => {
117
+ this . _destroyMenu ( ) ;
118
+
119
+ // If a click closed the menu, we should close the entire chain of nested menus.
120
+ if ( ( reason === 'click' || reason === 'tab' ) && this . _parentMenu ) {
121
+ this . _parentMenu . closed . emit ( reason ) ;
122
+ }
123
+ } ) ;
124
+ }
125
+ }
126
+ private _menu : MatMenuPanel ;
108
127
109
128
/** Data to be passed along to any lazily-rendered content. */
110
129
@Input ( 'matMenuTriggerData' ) menuData : any ;
@@ -151,16 +170,6 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
151
170
152
171
ngAfterContentInit ( ) {
153
172
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
173
this . _handleHover ( ) ;
165
174
}
166
175
@@ -203,7 +212,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
203
212
204
213
const overlayRef = this . _createOverlay ( ) ;
205
214
this . _setPosition ( overlayRef . getConfig ( ) . positionStrategy as FlexibleConnectedPositionStrategy ) ;
206
- overlayRef . attach ( this . _portal ) ;
215
+ overlayRef . attach ( this . _getPortal ( ) ) ;
207
216
208
217
if ( this . menu . lazyContent ) {
209
218
this . menu . lazyContent . attach ( this . menuData ) ;
@@ -347,7 +356,6 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
347
356
*/
348
357
private _createOverlay ( ) : OverlayRef {
349
358
if ( ! this . _overlayRef ) {
350
- this . _portal = new TemplatePortal ( this . menu . templateRef , this . _viewContainerRef ) ;
351
359
const config = this . _getOverlayConfig ( ) ;
352
360
this . _subscribeToPositions ( config . positionStrategy as FlexibleConnectedPositionStrategy ) ;
353
361
this . _overlayRef = this . _overlay . create ( config ) ;
@@ -531,4 +539,16 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
531
539
} ) ;
532
540
}
533
541
542
+ /** Gets the portal that should be attached to the overlay. */
543
+ private _getPortal ( ) : TemplatePortal {
544
+ // Note that we can avoid this check by keeping the portal on the menu panel.
545
+ // While it would be cleaner, we'd have to introduce another required method on
546
+ // `MatMenuPanel`, making it harder to consume.
547
+ if ( ! this . _portal || this . _portal . templateRef !== this . menu . templateRef ) {
548
+ this . _portal = new TemplatePortal ( this . menu . templateRef , this . _viewContainerRef ) ;
549
+ }
550
+
551
+ return this . _portal ;
552
+ }
553
+
534
554
}
0 commit comments