Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

md-menus not closing when using ng-repeat

<md-menu-bar>
  <md-menu ng-repeat="section in sections">
    <md-button class="navButton" ng-click="$mdOpenMenu()">
      {{section.name}}
    </md-button>
    <md-menu-content>
      <md-menu-item>
        <md-button>Subsection 1</md-button>
      </md-menu-item>
    </md-menu-content>
  </md-menu>
</md-menu-bar>

I am doing something like above but unfortunately, if I click a menu, it stays open even if I click other buttons.

I just want it to have the same behaviour as

https://material.angularjs.org/latest/demo/menuBar

P.S. If I don't use ng-repeat (meaning, menus are static), it works fine though.

Problem Codepen

like image 286
Rey Libutan Avatar asked Oct 14 '15 11:10

Rey Libutan


2 Answers

I just bumped into this question and noticed that the link posted by S.Klechkovski has a workaround made by christrude. It's not perfect (as other users pointed out) but at least it works. Might as well post it here.

You have to include the $mdMenu service in your controller and invoke its hide method when you click to open the menu.

$scope.closeOthers = function() {
  $mdMenu.hide(null, { closeAll: true });
}

and in the HTML

<button ng-click="closeOthers();$mdOpenMenu()">File</button>

Here's an edited Codepen. I hope it helps.

EDIT

The best solution is patching the component itself. Even with the disadvantages with the workaround found in Github (that I replicated here) it's still the best one.

However here's an alternative just for exploration purposes ;) This little frankenstein uses promises to only open the next menu when all the animations are done.

Markup

<button ng-click="closeOthers().then($mdOpenMenu);">File</button>

Controller

var lock = false;

$scope.closeOthers = function() {
  if(lock) {
    return;
  }

  var defer = $q.defer()
  lock = true;

  $mdMenu.hide(null, { closeAll: true }).then(function() {
    lock = false;
    defer.resolve();
  });

  return defer.promise;
}
like image 128
Ricardo Velhote Avatar answered Nov 12 '22 21:11

Ricardo Velhote


Good question! It seems that is known bug which is not yet fixed. I have added a comment with your example and some elaboration of the problem on the existing issue. Let's hope that it will be fixed soon.

Comment:

Here is an example Codepen that illustrates the reported issue.

After some research I noticed that it happens because md-menu directives use $scope.$emit for triggering the $mdMenuOpen event on which listen all md-menu instances. $emit triggers listeners on all parent scopes including the one on which the event is emitted. That means if all md-menu instances are on the same scope everything is fine but that is not the case with ng-repeat which creates new scope for each child.

like image 23
S.Klechkovski Avatar answered Nov 12 '22 19:11

S.Klechkovski