使用p-contextMenu和p-table时右键第二个表如何隐藏第一个表的菜单选项
问题根因
你将p-contextMenu定义在了可复用的app-data-table组件内部,每渲染一次app-data-table就会生成一个独立的右键菜单实例,PrimeNG默认不会在触发新的右键菜单时自动关闭其他组件实例的菜单,因此会出现多个菜单重叠显示的问题。
方案1:公共层复用单个contextMenu实例(推荐)
全局只维护一个右键菜单实例,不同表格右键时动态更新菜单配置,从根源避免多菜单重叠。
步骤1:调整Component-Box.html,把contextMenu移到公共层
<!-- Component-Box.html --> <p-contextMenu #globalCm [model]="currentMenuItems" appendTo="body"></p-contextMenu> <ng-template #tabdata> <p-scrollPanel [style]="{width: '100%', height: '100%'}"> <!-- 第一个表格绑定全局contextMenu --> <app-data-table [tradeList]="data" [selectedEntity]="entity" [entityData]="entityData" [contextMenu]="globalCm" (selectedTradeEvent)="fetchData($event)" (contextMenuTrigger)="updateMenu($event)"> </app-data-table> </p-scrollPanel> <p-scrollPanel [style]="{width: '100%', height: '100%'}"> <!-- 第二个表格绑定同一个全局contextMenu --> <app-data-table [tradeList]="table.value" [selectedEntity]="table.key" [entityData]="entityData" [contextMenu]="globalCm" (contextMenuTrigger)="updateMenu($event)"> </app-data-table> </p-scrollPanel> </ng-template>
步骤2:修改Data-Table-Component,接收公共contextMenu并触发右键事件
// Data-Table-Component.ts import { Input, Output, EventEmitter } from '@angular/core'; ... // 接收父组件传入的公共contextMenu @Input() contextMenu: any; // 右键行时向外传递事件 @Output() contextMenuTrigger = new EventEmitter<any>(); // 绑定到行的右键事件 onRowRightClick(event: MouseEvent, rowData: any) { this.contextMenuTrigger.emit({ event: event, rowData: rowData }); }
<!-- Data-Table-Component.html 调整对应绑定 --> <p-table [columns]="columns" [value]="tradeList" [(contextMenuSelection)]="selectedProduct" [contextMenu]="contextMenu" dataKey="id" [rowHover]=true styleClass="p-datatable-striped p-datatable-responsive-demo" selectionMode="multiple" [(selection)]="selectedTrade"> ... <ng-template pTemplate="body" let-block let-columns="columns" let-rowIndex="rowIndex"> <tr [pContextMenuRow]="block" [pSelectableRow]="block" [pSelectableRowIndex]="rowIndex" (contextmenu)="onRowRightClick($event, block)"> <td *ngFor="let col of getKeys(columns)" (click)=fetchDataArray(block)> {{block[col]}} </td> </tr> </ng-template> ...
步骤3:Component-Box.ts中处理菜单更新逻辑
// Component-Box.ts import { ViewChild } from '@angular/core'; import { ContextMenu } from 'primeng/contextmenu'; ... @ViewChild('globalCm') globalCm: ContextMenu; currentMenuItems = []; updateMenu(payload: any) { // 可根据表格类型、行数据动态生成不同菜单项,也可直接用固定配置 this.currentMenuItems = [ {label: 'Option 1',icon:'pi pi-user-edit'}, {label: 'Option 2',icon:'pi pi-user-edit'}, {label: 'Option 3',icon:'pi pi-user-edit'}, {label: 'Option 4',icon:'pi pi-user-edit'}, {label: 'Option 5',icon:'pi pi-user-edit'}, ]; // 手动触发菜单显示 this.globalCm.show(payload.event); }
方案2:最小改造方案(保留组件内contextMenu)
如果不想调整现有结构,直接在Data-Table-Component中添加全局右键监听,每次触发右键时先关闭当前组件的菜单即可:
// Data-Table-Component.ts import { ViewChild, HostListener } from '@angular/core'; import { ContextMenu } from 'primeng/contextmenu'; ... @ViewChild('cm') cm: ContextMenu; // 监听全局右键事件,先隐藏当前组件的菜单 @HostListener('document:contextmenu', ['$event']) onGlobalRightClick() { this.cm?.hide(); }
内容的提问来源于stack exchange,提问作者developer11
相关产品推荐
相关产品推荐

