diff --git a/src/lib/menu/menu-trigger.ts b/src/lib/menu/menu-trigger.ts index a290c0ccc2e..8b85c423764 100644 --- a/src/lib/menu/menu-trigger.ts +++ b/src/lib/menu/menu-trigger.ts @@ -214,9 +214,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 f83488fe30f..7f9a1bccfbd 100644 --- a/src/lib/menu/menu.spec.ts +++ b/src/lib/menu/menu.spec.ts @@ -961,6 +961,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'); + }); + + }); });