【问题标题】:Angular material menu opening on mouse hover鼠标悬停时打开角度材质菜单
【发布时间】:2016-01-28 11:16:30
【问题描述】:

我正在使用 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>

我现有的演示代码位于demo

【问题讨论】:

  • 你粘贴了完整的控制器代码吗?
  • 实际上根据angular material doc,控制器上的那些代码与演示相关。但是这些对于使用角度材料菜单栏本身并不是必需的。我的意思是我们可以忽略演示中的那些过滤器、配置和控制器。
  • 您最终找到解决方案了吗?
  • 不,还没有运气。等待角材料修复它。
  • 您应该在子菜单而不是父菜单上的 mouseenter 上停止事件传播。

标签: angularjs submenu menubar angular-material


【解决方案1】:

很简单,这里有一个答案,如果你使用bower安装angular-material,你需要:

  1. 转到/bower-components/angular-material/modules/js文件夹
  2. 在任何测试编辑器(例如可视化代码、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();
};

【讨论】:

  • 不接受修改源代码,因为每次更新包都会覆盖更改。
【解决方案2】:

很遗憾,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()
猜你喜欢
  • 2017-12-25
  • 2021-02-20
  • 2018-10-05
  • 2019-03-24
  • 1970-01-01
  • 2021-04-28
  • 2019-02-20
  • 1970-01-01
  • 2011-06-22
相关资源
最近更新 更多