我正在开发 Angular 7 应用程序,它有 primeNg menuBar,我想为顶级菜单项(应该打开二级菜单项列表)和二级菜单项(应该直接转到为此提供的 routerlink)实现快捷方式菜单项)。
我的做法:
- 对于菜单,我有 JSON 文件来定义不同的菜单项。在这个 Json 文件中,我添加了一个新属性“shortKey”——它定义了用于该菜单项的快捷键。
- 使用上面的 json,创建了 primeNg menuItems 数组。在这里,我正在检查 menuItem 是否有可用的短键,然后使用 Angulr2-Hotkeys 为该短键绑定 keyBoardEvent。
- 在键盘事件的回调中,对于顶层菜单:
- 使用 querySelector 查找顶级菜单项并更改该 dom 元素的 css 样式以显示菜单。
- 根据该菜单项的 routerLink 导航到组件。
我使用上述方法面临的问题:
- 显示顶级菜单后,我需要在文档中其他任何位置的点击事件中隐藏它。因此,文档上的侦听器将一直在侦听。
- 过多的直接 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. 如果方法没问题,我该如何缓解上述问题?