diff --git a/src/lib/menu/menu-content.ts b/src/lib/menu/menu-content.ts index e8d16b824ea5..2329777becb5 100644 --- a/src/lib/menu/menu-content.ts +++ b/src/lib/menu/menu-content.ts @@ -18,6 +18,7 @@ import { } from '@angular/core'; import {TemplatePortal, DomPortalOutlet} from '@angular/cdk/portal'; import {DOCUMENT} from '@angular/common'; +import {Subject} from 'rxjs'; /** * Menu content that will be rendered lazily once the menu is opened. @@ -29,6 +30,9 @@ export class MatMenuContent implements OnDestroy { private _portal: TemplatePortal; private _outlet: DomPortalOutlet; + /** Emits when the menu content has been attached. */ + _attached = new Subject(); + constructor( private _template: TemplateRef, private _componentFactoryResolver: ComponentFactoryResolver, @@ -60,6 +64,7 @@ export class MatMenuContent implements OnDestroy { // risk it staying attached to a pane that's no longer in the DOM. element.parentNode!.insertBefore(this._outlet.outletElement, element); this._portal.attach(this._outlet, context); + this._attached.next(); } /** diff --git a/src/lib/menu/menu-trigger.ts b/src/lib/menu/menu-trigger.ts index a099665a3b66..b2895608564a 100644 --- a/src/lib/menu/menu-trigger.ts +++ b/src/lib/menu/menu-trigger.ts @@ -245,9 +245,14 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy { if (menu.lazyContent) { // Wait for the exit animation to finish before detaching the content. menu._animationDone - .pipe(filter(event => event.toState === 'void'), take(1)) - .subscribe(() => { - menu.lazyContent!.detach(); + .pipe( + filter(event => event.toState === 'void'), + take(1), + // Interrupt if the content got re-attached. + takeUntil(menu.lazyContent._attached) + ) + .subscribe(() => menu.lazyContent!.detach(), undefined, () => { + // No matter whether the content got re-attached, reset the menu. this._resetMenu(); }); } else {