电子文本中的上下文菜单堆叠

我正在构build一个基于Electron的应用程序,其中包含一个包含唯一行的网格。 我想要一个特定于每一行的上下文菜单。 这里是一个例子:

与上下文菜单的GUI的图像

虽然这个截图被裁剪,你可以看到有多行,每行包含单独的数据。 由于我想右键单击一行并得到一个独特的上下文菜单,我已经实现了电子上下文菜单 ,它在第一次右键单击时工作,但随后的右键单击会导致上下文菜单的叠加效果。

具体来说,这是发生了什么:

  1. 我右键单击行1,并显示正确的上下文菜单
  2. 我右键单击第2行,重复的行1的上下文菜单显示,然后行2的上下文菜单显示出来。 (注意在屏幕截图中显示的上下文菜单不对应我的鼠标结束的行)
  3. 这个重演。

在React.JS中,这是我的侦听器,它收集electron-context-menu模块所需的contextmenu对象:

  handleContextMenu() { this.props.contextMenu({ window: electron.remote.BrowserWindow.getFocusedWindow(), prepend: (params, browserWindow) => [{ label: `Library Compare ${this.state.msn}`, click: () => this.runLibCompare() }], append: (params, browserWindow) => [{ label: '---', }] }) }; 

其中this.props.contextMenu(...)将React.JS组件传递到以下位置:

 const contextMenu = eRequire('electron-context-menu'); 

我做了一些大规模的debugging,我不认为这个问题是模块。 我使用的模块基本上组织关于上下文菜单的信息,然后使用electron.remote函数和来自电子内部的menu.popup函数。 这是一个链接到github中的特定行 。

 const menu = (electron.Menu || electron.remote.Menu).buildFromTemplate(menuTpl); menu.popup(electron.remote ? electron.remote.getCurrentWindow() : win); 

这个对menu.popup调用导致了这一行的电子 。

  const remoteMemberFunction = function (...args) { if (this && this.constructor === remoteMemberFunction) { // Constructor call. let ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CONSTRUCTOR', metaId, member.name, wrapArgs(args)) return metaToValue(ret) } else { // Call member function. let ret = ipcRenderer.sendSync('ELECTRON_BROWSER_MEMBER_CALL', metaId, member.name, wrapArgs(args)) return metaToValue(ret) } 

}

所以我看到一个调用ipcRender.sendSync – 但是当我在ipcMain 的这些调用的接收器中添加debugging语句,我没有看到任何输出!

 ipcMain.on('ELECTRON_BROWSER_MEMBER_CALL', function (event, id, method, args) { try { args = unwrapArgs(event.sender, args) let obj = objectsRegistry.get(id) if (obj == null) { throwRPCError(`Cannot call function '${method}' on missing remote object ${id}`) } callFunction(event, obj[method], obj, args) } catch (error) { event.returnValue = exceptionToMeta(error) } }) 

当我添加到上述函数的debugging语句时,我没有看到任何输出。 那就是我寻找他墙的地方。

我正在使用电子1.4.15。 我知道这个问题应该是可以解决的,毕竟Atom IDE(基于电子的)并没有这个问题,即使它有多个上下文菜单。

我觉得有一些内存需要清理,我不知道如何清除以前的上下文菜单堆栈!

我通过首先使用e.target获取点击的目标来解决这个问题。 然后,根据这个,我调用相应的contextmenu。 如果目标命中不在我的应用程序的目标列表中,我使用默认的contextmenu。

 window.addEventListener( "contextmenu", e => { e.preventDefault(); if (e.target.id === 'fullscr'){ console.log(e && e.target); // e.preventDefault(); mymenu.popup(remote.getCurrentWindow()); }else{ editmenu.popup(remote.getCurrentWindow()); } console.log(e.which); }, false );