【问题标题】:When closing a BrowserWindow in electron, event listeners continue to reference the BrowserWindow在 electron 中关闭 BrowserWindow 时,事件监听器会继续引用 BrowserWindow
【发布时间】:2019-11-30 07:19:46
【问题描述】:

我的标题可能没有正确捕捉到我的问题,但我找不到简洁的方法来捕捉这个问题。

问题是这样的:

我有一个由 IPC 事件触发的 BrowserWindow。当 BroswerWindow 打开时,它会向主进程发送一条消息,表明它已完成加载,然后主进程会向它发送一些数据以执行特定任务。任务完成后,用户关闭窗口并开始执行不同的进程。

这一切都很好,除了应用程序接收到该事件以再次打开 BrowserWindow 之外,将数据发送到新窗口的事件处理程序要么抛出一个错误,指示它无法将数据发送到窗口,因为进程已经销毁或重新打开窗口,但使用第一次打开窗口时的所有旧数据,当时我需要的是窗口的新实例。我知道我可以简单地使用 javascript 来拆除并重新生成原始 HTML,但我觉得必须有更好的方法。下面是代码:

ma​​in.js

const electron = require ("electron");
const ipcMain = require('electron').ipcMain;
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
function openNewWindow() {
    let win = new BrowserWindow({ autoHideMenuBar: true });
    win.loadURL(__dirname + '\\new_window.html');
    win.webContents.openDevTools()
    win.on('closed', function () {
       win = null;
    })
    return win
};

let mainWindow;

app.on('window-all-closed', function () {
   if (process.platform != 'darwin') {
     app.quit ();
   }
});

app.on('ready', function () {
   mainWindow = new BrowserWindow ({
                    title: app.getName() + " - v" + app.getVersion(),
                    autoHideMenuBar: true
   });

   mainWindow.loadURL ('file://' + __dirname + '/index.html');

    //This event handler opens the new window when it receives the open-new-window event
    ipcMain.on('open-new-window', (event,arg) => {
        console.log('Arg = ' + arg);
        let newWindow = openNewWindow();
        //This event handler sends data to the new window when the new window indicates that it is done loading
        ipcMain.on('done-loading',(event2,arg2) => {
            console.log(arg2);
            newWindow.webContents.send('test',arg);
        });
    });

   // Close the application when the window is closed
   mainWindow.on ('closed', function() {
     mainWindow = null;
   });
});

错误信息中对第 52 行的引用就是这一行:

newWindow.webContents.send('test',arg);

新窗口打开,但没有数据发送给它。

【问题讨论】:

  • 而不是使用ipcMain 'done-loading'事件尝试BrowserWindow ready-to-show参考this
  • @Eldar 谢谢,但似乎没有用。我需要它在发送数据之前加载所有 javascript,而不仅仅是渲染 html。另外,我不清楚这是否会解决基本问题。

标签: javascript electron


【解决方案1】:

问题类似于this问题。

每个open-new-window 事件都会使您重新订阅ipcMain 到新窗口的done-loading 事件,但它仍然保持对旧窗口的订阅/关闭。

您不想在新窗口处理程序中执行ipcMain.on("done-loading", ...)

您想在窗口处理程序之外执行此操作,而是使用 event 参数将响应发送回相同的 Web 内容:

ipcMain.on('open-new-window', (event, arg) => {
    openNewWindow();
});

ipcMain.on('done-loading', (event, arg) => {
    event.sender.send('test', arg);
});

但是,有一个 did-finish-load 事件可以执行您似乎想做的事情:

function openNewWindow() {
    let win = new BrowserWindow({ autoHideMenuBar: true });
    win.loadURL(__dirname + '\\new_window.html');
    win.webContents.once("did-finish-load", () => {
        win.webContents.send("test", ...);
    });
};

【讨论】:

  • 是的,看起来确实是这样……问题是我需要能够从 open-new-window 事件中访问 arg 变量。我想我可以将一个事件发送回发送 open-new-window 事件的窗口,并告诉它在完成加载触发后发送 arg。或者我可以将 arg 分配给 main.js 中的全局变量。谢谢!如果可行,我会尝试并接受答案!
  • 您可以获取 created-window 并将其 id 映射到 arg。我不知道是什么发送了done-loading 事件,但它可以将窗口 ID 作为 arg 发送,因此您可以查找要发送到窗口的 arg。这是一个想法
猜你喜欢
  • 1970-01-01
  • 2017-05-04
  • 2018-11-04
  • 2017-01-30
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 2016-11-19
相关资源
最近更新 更多