2

我正在开发 Angular 7 应用程序,它有 primeNg menuBar,我想为顶级菜单项(应该打开二级菜单项列表)和二级菜单项(应该直接转到为此提供的 routerlink)实现快捷方式菜单项)。

我的做法:

  1. 对于菜单,我有 JSON 文件来定义不同的菜单项。在这个 Json 文件中,我添加了一个新属性“shortKey”——它定义了用于该菜单项的快捷键。
  2. 使用上面的 json,创建了 primeNg menuItems 数组。在这里,我正在检查 menuItem 是否有可用的短键,然后使用 Angulr2-Hotkeys 为该短键绑定 keyBoardEvent。
  3. 在键盘事件的回调中,对于顶层菜单:
    • 使用 querySelector 查找顶级菜单项并更改该 dom 元素的 css 样式以显示菜单。
    • 根据该菜单项的 routerLink 导航到组件。

我使用上述方法面临的问题:

  1. 显示顶级菜单后,我需要在文档中其他任何位置的点击事件中隐藏它。因此,文档上的侦听器将一直在侦听。
  2. 过多的直接 dom 交互和 dom 操作。

具有 PrimeNg 菜单的组件

import { Component, OnInit, Renderer2 } from '@angular/core';
import { MenuItem } from 'primeng/api';
import { HotkeysService, Hotkey } from 'angular2-hotkeys';
import { NavItem } from '../NavItem';
import { MenuItemContent } from 'primeng/menu';
import { BindHotKeyService } from '../bind-hot-key.service';


@Component({
  selector: 'app-ng-prime-menu',
  templateUrl: './ng-prime-menu.component.html',
  styleUrls: ['./ng-prime-menu.component.scss']
})
export class NgPrimeMenuComponent implements OnInit {
  private items: MenuItem[] = [];
  bindHotKeyService: BindHotKeyService;

  constructor(bindHotKeyService: BindHotKeyService) {
    this.bindHotKeyService = bindHotKeyService;
  }
  ngOnInit() {
    let navItems: NavItem[] = this.getNavItems();
    navItems.forEach(element => {
      let m1: MenuItem = {};
      let mItemsInside: MenuItem[] = [];
      m1.label = element.label;
      m1.id="id_"+m1.label;
      element.shortKey !== ''? this.bindHotKeyService.bindHotKey("menuNavigation",element.shortKey, element.label):"";
      element.navItems.forEach(insideEl => {
        let m1Inside: MenuItem = {};
        m1Inside.label = insideEl.label;
        insideEl.shortKey !== ''? this.bindHotKeyService.bindHotKey("menuItemClick",insideEl.shortKey, insideEl.label):"";
        mItemsInside.push(m1Inside);
      });
      m1.items = mItemsInside;
      this.items.push(m1);
    });

  }
}

绑定键盘事件的服务(只是一个草稿)

import { Injectable, Renderer2, RendererFactory2 } from '@angular/core';
import { HotkeysService, Hotkey } from 'angular2-hotkeys';

@Injectable({
  providedIn: 'root'
})
export class BindHotKeyService {
  private renderer: Renderer2;

  constructor(private hkservice: HotkeysService, rendererFactory: RendererFactory2) {
    this.renderer = rendererFactory.createRenderer(null, null);
   }
  bindHotKey(type: string, key: string, menuItemName: string): void {
    if (type === 'menuNavigation') {
      let menuItemId: string =  "#id_"+menuItemName;
      this.hkservice.add(new Hotkey(key, (event: KeyboardEvent): boolean => {
        let menuBar:Element = document.querySelector("p-menubar");
        let menuItemChildNode:Element = menuBar.querySelector(menuItemId);
        menuItemChildNode.parentElement.className = menuItemChildNode.parentElement.className+" ui-menuitem-active";
        menuItemChildNode.parentElement.querySelector("ul").style.zIndex = 
        (Number(menuItemChildNode.parentElement.querySelector("ul").style.zIndex) + 2).toString();
        console.log("Binding HotKey: '" + key + "' to MenuItem: " + menuItemName);
        return false;
      }));
    }
  }
}

**component HTML**
<p-menubar [model]="items" [autoDisplay]="false"> 
</p-menubar>

我的问题: 1.上述方法对于在 Angular 7 中使用 PrimeNg 菜单绑定键是否正确?如果不是,有什么更好的解决方案?2. 如果方法没问题,我该如何缓解上述问题?

4

0 回答 0