首页 > 解决方案 > Windows 上 Electron 中的 dialog.showOpenDialog 有问题吗?

问题描述

我正在研究书中的一个例子,似乎无法超越这一点。当我按 Ctrl-o 时,它会显示打开文件的对话框,但它永远不会将文件加载到标记编辑器中。但是,如果我使用 VSCode 中的调试器运行它,它工作正常。

我相信这个部分的问题是:

dialog.showOpenDialog(window, options, paths => {
    if (paths && paths.length > 0) {
      const content = fs.readFileSync(paths[0]).toString();
      window.webContents.send('load', content);
    }
  });

这是我的 menu.js 文件:

const { 
    app,
    Menu,
    shell,
    ipcMain,
    BrowserWindow,
    globalShortcut,
    dialog
} = require('electron');

const fs = require('fs');

function saveFile() {
  console.log('Saving the file');

  const window = BrowserWindow.getFocusedWindow();
  window.webContents.send('editor-event', 'save');
}

function loadFile() {
  console.log('loadFile confirmation');
  const window = BrowserWindow.getFocusedWindow();
  const options = {
    title: 'Pick a markdown file',
    filters: [
      { name: 'Markdown files', extensions: ['md'] },
      { name: 'Text files', extensions: ['txt'] }
    ]
  };


  dialog.showOpenDialog(window, options, paths => {
    if (paths && paths.length > 0) {
      const content = fs.readFileSync(paths[0]).toString();
      window.webContents.send('load', content);
    }
  });
}





app.on('ready', () => {
    globalShortcut.register('CommandOrControl+S', () => {
      saveFile();
    });

       globalShortcut.register('CommandorControl+O', () => {
         console.log('Ctrl-O received');
         loadFile();
       });
      });
     
  


ipcMain.on('save', (event, arg) => {
    console.log(`Saving content of the file`);
    console.log(arg);
  
    const window = BrowserWindow.getFocusedWindow();
    const options = {
      title: 'Save markdown file',
      filters: [
        {
          name: 'MyFile',
          extensions: ['md']
        }
      ]
    };

    
  
    //Broken code from book apparently: dialog.showSaveDialog(window, options, filename => {
      let filename = dialog.showSaveDialogSync(window, options);
      console.log(filename);
      if (filename) {
        console.log(`Saving content to the file: ${filename}`);
        fs.writeFileSync(filename, arg);
      }
    //Broken code from book apparently });
    
  });

ipcMain.on('editor-reply', (event, arg) => {
    console.log(`Receieved reply from web page: ${arg}`);
});



const template = [
    {
        label: 'Format',
        submenu: [
            {
                label: 'Toggle Bold',
                click() {
                    const window = BrowserWindow.getFocusedWindow();
                    window.webContents.send('editor-event',
                    'toggle-bold'
                    );
                    
                }
                
      
                
            }
        ]
    }
];

if (process.env.DEBUG) {
  template.push({
    label: 'Debugging',
    submenu: [
      {
        label: 'Dev Tools',
        role: 'toggleDevTools'
      },

      {type: 'separator' },
      {
        role: 'reload',
        accelerator: 'Alt+R'
      }
    ]
  });
}


const menu = Menu.buildFromTemplate(template);

module.exports = menu;

我的 index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta 
    http-equiv="Content-Security-Policy"
    content="script-src 'self' 'unsafe-inline';" />
    <style>
        html, body {
            height: 100%;
            display: flex;
            flex: 1;
            flex-direction: column;
        }
        .CodeMirror {
            flex: 1;
        }
    </style>

    <title>Document</title>
    <link rel="stylesheet" href="./node_modules/simplemde/dist/simplemde.min.css">
    <script src="./node_modules/simplemde/dist/simplemde.min.js"></script>
    


</head>
<body>
    <textarea id="editor"></textarea>

    <script>
        var editor = new SimpleMDE({
            element: document.getElementById('editor')
        });
        const { ipcRenderer }  = require('electron');
        ipcRenderer.on('editor-event', (event, arg) => {
            console.log(arg);
            
            event.sender.send('editor-reply', `Received ${arg}`);
            if (arg === 'toggle-bold') {
                editor.toggleBold();
            }
            if (arg === 'save') {
                event.sender.send('save', editor.value());
            }
            
        });
        ipcRenderer.on('load', (event, content) => {
            if (content) {
                editor.value(content);
            }
        });

        
        ipcRenderer.send('editor-reply', 'Page Loaded');

    </script>
    
</body>
</html>

标签: node.jswindowselectron

解决方案


TLDRdialog.showOpenDialog :将inside的回调更改为loadFile

dialog.showOpenDialog(window, options, (canceled, paths) => {

代替:

dialog.showOpenDialog(window, options, paths => {

长版:

dialog.showOpenDialog传入 3 个参数的回调:

  • canceled
  • filePaths
  • 并且仅在 Mac 上:bookmarks

你想要第二个参数filePaths,尽管如果你的回调只是:paths => {期望只有一个参数 Electron 会传入canceled参数,因为它是第一个参数,而你只说你想要一个参数。

所以这意味着你需要在paths像之前传递一个参数:(canceled, paths) => {

查看文档


推荐阅读