diff --git a/src/lib/menu/menu-trigger.ts b/src/lib/menu/menu-trigger.ts index bbcfe673daaa..b159e5398e0b 100644 --- a/src/lib/menu/menu-trigger.ts +++ b/src/lib/menu/menu-trigger.ts @@ -204,9 +204,10 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy { /** Closes the menu. */ closeMenu(): void { if (this._overlayRef && this.menuOpen) { + this._resetMenu(); this._overlayRef.detach(); this._closeSubscription.unsubscribe(); - this._resetMenu(); + this.menu.close.emit(); if (this.menu instanceof MdMenu) { this.menu._resetAnimation(); diff --git a/src/lib/menu/menu.spec.ts b/src/lib/menu/menu.spec.ts index 775a6826f5f7..fc9e96a61063 100644 --- a/src/lib/menu/menu.spec.ts +++ b/src/lib/menu/menu.spec.ts @@ -966,6 +966,28 @@ describe('MdMenu', () => { .not.toContain('mat-elevation-z3', 'Expected no stacked elevation.'); }); + it('should close all of the menus when the root is closed programmatically', () => { + compileTestComponent(); + instance.rootTrigger.openMenu(); + fixture.detectChanges(); + + instance.levelOneTrigger.openMenu(); + fixture.detectChanges(); + + instance.levelTwoTrigger.openMenu(); + fixture.detectChanges(); + + const menus = overlay.querySelectorAll('.mat-menu-panel'); + + expect(menus.length).toBe(3, 'Expected three open menus'); + + instance.rootTrigger.closeMenu(); + fixture.detectChanges(); + + expect(overlay.querySelectorAll('.mat-menu-panel').length).toBe(0, 'Expected no open menus'); + }); + + }); });