menu: when md-menu is removed from the DOM via ng-if, while open, the backdrop is not destroyed
Bug, enhancement request, or proposal: Bug
CodePen and steps to reproduce the issue:
https://codepen.io/anon/pen/OBmMjL
Detailed Reproduction Steps:
- This is modified example - you will find two same icon menu buttons.
- Press first button.
- Now second button does not work, you are not able to click anywhere as backdrop was not destroyed.
What is the expected behavior?
Backdrop is destroyed.
What is the current behavior?
Backdrop is not destroyed. App is no longer working, user should press F5.
What is the use-case or motivation for changing an existing behavior?
In this example I am removing menu button using "ng-if" -- this is not the life case, however menu button may be removed by something else i.e. http callback. This also can be reproduced on pretty any angularjs material app (which has menu button) using mouse and keyboard -- after focusing menu button: click on menu button with enter and browser back with mouse at the ~same time. Together with https://github.com/angular/material/issues/11480 this means that using like ng-if="resultOfHttpRequest" on any menu button might make js app completely unresponsive from user point of view.
Which versions of AngularJS, Material, OS, and browsers are affected?
- AngularJS: 1.6.7 (1.5.9)
- AngularJS Material: 1.1.10 (1.1.5)
- OS: windows
- Browsers: chrome
Is there anything else we should know? Stack Traces, Screenshots, etc.
You should make sure that the menu has been closed before removing the md-menu and its contents from the DOM. At this time, we don't expose the Promise from calling $mdMenu.open($event) so it's not so simple to figure out if the menu is open or not. However you can check the trigger's aria-expanded attribute like this example.
If you wanted to be more elegant, you could use a MutationObserver with an attrs.$observe() fallback instead of the $interval in my quick example.
We should look into the code in https://github.com/angular/material/blob/master/src/core/services/interimElement/interimElement.js and https://github.com/angular/material/blob/master/src/components/menu/js/menuServiceProvider.js to see why opts.hideBackdrop() is not being called in this case. It's possible that in the ng-if case, we aren't handling things properly. From the comments, it appears that we were thinking mostly about navigation triggered $destroy events and normal interactions (mouse, keyboard) to handle cleaning things up.
I understand that in lof of cases menu should not be removed with ng-if, however fact that
This also can be reproduced on pretty any angularjs material app (which has menu button) using mouse and keyboard -- after focusing menu button: click on menu button with enter and browser back with mouse at the ~same time.
make me think that something is not good.