Angular Material菜单在鼠标悬停时如何打开

10

我正在使用Angular Material菜单栏来显示菜单和每个菜单项下的子菜单。我已经添加了ng-click事件来打开子菜单。但是菜单仍然在鼠标悬停在父菜单项上时打开。不仅如此,由于我有两个子菜单,对于第一个子菜单项,子菜单在鼠标悬停时打开,但第二个子菜单在鼠标悬停时没有打开。请问如何停止菜单在鼠标悬停时打开。我尝试在父菜单项的mouseenter事件上停止事件传播。但是在打开第二个子菜单时,第一个子菜单没有被隐藏。请帮我解决这个问题。

<div ng-controller="DemoBasicCtrl as ctrl" ng-cloak="" class="menuBardemoBasicUsage" ng-app="MyApp">

    <md-menu-bar>
      <md-menu>
        <button ng-click="$mdOpenMenu()">
          File
        </button>
        <md-menu-content>
          <md-menu-item>
            <md-menu>
              <md-button ng-click="$mdOpenMenu()">New</md-button>
              <md-menu-content>
                <md-menu-item><md-button ng-click="ctrl.sampleAction('New Document', $event)">Document</md-button></md-menu-item>
              </md-menu-content>
            </md-menu>
          </md-menu-item>
                        <md-menu-item>
            <md-menu>
              <md-button ng-click="$mdOpenMenu()">New</md-button>
              <md-menu-content>
                <md-menu-item><md-button ng-click="ctrl.sampleAction('New Document', $event)">Document</md-button></md-menu-item>
              </md-menu-content>
            </md-menu>
          </md-menu-item>

        </md-menu-content>
      </md-menu>

    </md-menu-bar>

我现有的演示代码在这里


你是否已经粘贴了完整的控制器代码? - Sajeetharan
实际上,根据Angular Material文档,控制器上的那些代码与演示相关。但是,在使用Angular Material菜单栏本身时,这些并不是必需的。我的意思是,我们可以忽略演示中的那些过滤器、配置和控制器。 - Indranil Mondal
你最后找到解决方案了吗? - adamdport
还没有,需要等待 Angular Material 修复它。 - Indranil Mondal
应该在子菜单的mouseenter事件上停止事件传播,而不是在父元素上停止。 - Adrien
2个回答

4

很遗憾,Google没有修复许多Angular Material 1的问题,而是支持版本2。
我认为这可能是鼓励人们切换到Angular v2的一种方式...

无论如何,我通过停止菜单项上的事件传播来解决了悬停问题。然后在子菜单容器上添加了一个"鼠标离开"事件处理程序,关闭当前菜单。

控制器 -

    $scope.noop = function(event){
        event.stopImmediatePropagation();
    };

    $scope.closeSubMenu = function(event){
        mdMenu.hide();
    }

视图 -
<md-menu-item ng-repeat="item in menu.items" >
    <md-menu-item>
        <md-menu>
            <md-button ng-click="$mdOpenMenu($event)" ng-mouseenter="noop($event)">{{item.title}}</md-button>
            <md-menu-content ng-mouseleave="closeSubMenu($event)" >
                <md-menu-item ng-repeat="subitem in item.items">
                    <md-button ng-click="$location.url(subitem.location)">{{subitem.title}}</md-button>
                </md-menu-item>
            </md-menu-content>
        </md-menu>
    </md-menu-item>
</md-menu-item>

请注意,在您的控制器中,您应该像参数一样通知$mdMenu并将mdMenu.hide()更改为$mdMenu.hide() - rflmyk

-2

这很简单,以下是答案,如果您使用bower安装angular-material,则需要:

  1. 进入/bower-components/angular-material/modules/js文件夹
  2. 在任何测试编辑器(如Visual Code、Sublime或Atom)中打开menu.js
  3. 找到此行this.handleMenuItemHover = function(event) {

然后使用我的修复方法:

this.handleMenuItemHover = function(event) {
if (self.isAlreadyOpening) return;
var nestedMenu = (
  event.target.querySelector('md-menu')
    || $mdUtil.getClosest(event.target, 'MD-MENU')
);
openMenuTimeout = $timeout(function() {
  if (nestedMenu) {
    nestedMenu = angular.element(nestedMenu).controller('mdMenu');
  }
  if (self.currentlyOpenMenu && self.currentlyOpenMenu != nestedMenu)    
 {
    var closeTo = self.nestLevel + 1;
    self.currentlyOpenMenu.close(true, { closeTo: closeTo });

    /******* david zhao: fix codes ******/
    if (!!nestedMenu) {
      self.isAlreadyOpening = true;
      nestedMenu.open();
    }

  } else if (nestedMenu && !nestedMenu.isOpen && nestedMenu.open) {
    self.isAlreadyOpening = true;
    nestedMenu.open();
  }
}, nestedMenu ? 100 : 250);
var focusableTarget = 
 event.currentTarget.querySelector('.md-button:not([disabled])');
focusableTarget && focusableTarget.focus();
};

3
每次软件包更新时,源代码的修改都会被覆盖,因此这种做法是不可接受的。 - adamdport

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接