在 Electron.js 中进行确认

问题描述 投票:0回答:1

我想在 Electron.js 应用程序中制作一个包含“是”和“否”按钮的消息框。我尝试用电子内部的dialog来做到这一点。但没有成功:

const electron = require('electron')
const { dialog } = electron
console.log(dialog) // undefined
const electron = require('electron')
const dialog = electron.remote.dialog
console.log(dialog) // Uncaught Error: Cannot read "dialog" of undefined (remote is undefined)

然后,我尝试使用 dialog 来实现,它是 npm 中的一个模块。但它没有做我想做的事情。没有任何是或否按钮,当我单击“确定”或关闭窗口时,它也返回相同的响应:

const electron = require('electron')
const dialog = require('dialog')
dialog.info('Are you sure?', 'Confirmation', function(exitCode) {
        if (exitCode == 0) {
                // Should clicked OK (always response)
        }
        if (exitCode == 1) {
                // Should closed window (but never works)
        }
})

我做错了什么?

node.js electron dialog
1个回答
4
投票

您会想要使用 电子的

dialog.showMessageBox();
方法。

dialog.showMessageBoxSync(); 方法会阻塞你的主进程,直到收到响应,所以除非有意,否则你不会想使用它。


我已将对话框的创建和管理放在

main.js
文件中。如果你想把它移到它的 自己的文件,这不是问题。如果您想要对话框,您需要做的就是
get()
(主)窗口实例 框成为主窗口的子窗口。

main.js
(主要流程)

// Import required Electron modules
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronDialog = require('electron').dialog;
const electronIpcMain = require('electron').ipcMain;

// Import required Node modules
const nodePath = require('path');

// Prevent garbage collection
let window;

function createWindow() {
    const window = new electronBrowserWindow({
        x: 0,
        y: 0,
        width: 800,
        height: 600,
        show: false,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            preload: nodePath.join(__dirname, 'preload.js')
        }
    });

    window.loadFile('index.html')
        .then(() => { window.show(); });

    return window;
}

electronApp.on('ready', () => {
    window = createWindow();
});

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

electronApp.on('activate', () => {
    if (electronBrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});

// ---

electronIpcMain.on('openDialog', () => {
    electronDialog.showMessageBox(window, {
        'type': 'question',
        'title': 'Confirmation',
        'message': "Are you sure?",
        'buttons': [
            'Yes',
            'No'
        ]
    })
        // Dialog returns a promise so let's handle it correctly
        .then((result) => {
            // Bail if the user pressed "No" or escaped (ESC) from the dialog box
            if (result.response !== 0) { return; }

            // Testing.
            if (result.response === 0) {
                console.log('The "Yes" button was pressed (main process)');
            }

            // Reply to the render process
            window.webContents.send('dialogResponse', result.response);
        })
})

为了进程之间的正确通信,我们必须 使用进程间通信

preload.js
(主要流程)

// Import the necessary Electron modules
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;

// Exposed protected methods in the render process
contextBridge.exposeInMainWorld(
    // Allowed 'ipcRenderer' methods
    'ipcRenderer', {
        // From render to main
        openDialog: () => {
            ipcRenderer.send('openDialog');
        },
        // From main to render
        dialogResponse: (response) => {
            ipcRenderer.on('dialogResponse', response);
        }
    }
);

最后,您的

index.html
文件将监听按钮单击。点击后,发送消息给主进程打开 这 对话框。

一旦从对话框收到有效响应,响应就会被发送回渲染进程进行处理。

PS:渲染图 方法

ipcRenderer.invoke()
可以用来代替
ipcRenderer.send()
方法。 但如果是这样,您将需要在渲染过程中处理“否”或转义 (ESC) 响应。

index.html
(渲染过程)

<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Electron Test</title>
        <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
    </head>

    <body>
        <input type="button" id="openDialog" value="Show Dialog">

        <hr>

        <div id="response"></div>
    </body>

    <script>
        // Open dialog (in main process) when "Show Dialog" button is clicked
        document.getElementById('openDialog').addEventListener('click', () => {
            window.ipcRenderer.openDialog('openDialog');
        })

        // Response from main process
        window.ipcRenderer.dialogResponse((event, response) => {
            if (response === 0) {
                // Perform your render action here
                document.getElementById('response').innerText = 'The "Yes" button was clicked';
            }
        });
    </script>
</html>

要在对话框中使用 2 个以上按钮,在创建对话框时您可能需要指定 a

cancelId
并在执行任何操作之前检查所有有效的返回值。

© www.soinside.com 2019 - 2024. All rights reserved.