将一些初始数据传递到新窗口的正确方法是什么?

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

我只是在学习Electron,我正在尝试打开一个文件并在新窗口中显示它。我在初始(根)窗口中单击一个按钮,然后打开“打开文件”对话框,从中可以获取文件路径。然后,我想打开该文件,创建一个窗口,然后将文件的内容传递到新窗口。我的问题是在窗口准备就绪时,将带有文件内容的字符串放入回调函数中。我什至可能吗?我的main.js代码:

function createWindow (templateFile, initialData) 
{  console.log("Creating window....")
   newWindow = new BrowserWindow({width: 800,
                                  height: 600,
                                  webPreferences: {preload: path.join(__dirname, 'preload.js'),
                                                   nodeIntegration: true}
                                 })
    newWindow.loadFile(templateFile)
    newWindow.webContents.openDevTools()
//This is what doesn't work; I want to take the initialData argument to the createWindow function, 
//and get it into the 'did-finish-load' callback function
    newWindow.webContents.on('did-finish-load', (event, initialData) => 
    {   windowsArray[newWindow.webContents.id] = newWindow 
        console.log(initialData)
        newWindow.webContents.send("initialDataLoad", initialData)
    })
    newWindow.on('closed', function () {newWindow.object = null})
}

ipcMain.on("new-sheet", (event, gameDefinitionFile) => 
{    console.log("Loading " + gameDefinitionFile)
     let gameDefContents
     fs.readFile(gameDefinitionFile, 'ascii', (err, gameDefContents) => {})
     createWindow("defaultSheet.html", gameDefContents)
})

我已经阅读过,您可以在webContents对象上创建一个新属性,然后在渲染器过程中引用它,但这听起来不像是正确的做法。所以,我该怎么办?

https://gitlab.com/sjbrown8/osiris处的完整代码

javascript electron ipc
2个回答
0
投票

webContents方式应该可以轻松解决您的问题。简单明了:您可以预先创建并收集窗口所需的所有数据,然后使用该窗口生成窗口。

webContents方式有一些限制,因为您在webContents上创建的main对象已序列化并发送到render-,这意味着两个进程都有该对象的独立版本:

  1. 您在数据的呈现过程版本上应用于对象的更改将不会反映到主对象中(反之亦然)
  2. 您不能传递函数(例如使用该函数在渲染过程中从main调用函数)

但是使用简单的初始化数据:容易理解。

编辑:

当然,发送方法需要一个通道名称和一个可选的对象,即要发送的数据。您可以这样编写一个函数:

sendPersonData(personData) => {
   webContents.send('person-data-updated', personData);
);

或者如果您想要一个需要回调以灵活发送的函数:

updatePersonData(personData, senderCallback) => {
   updatedPersonData = functionToUpdatePersonData(personData);
   senderCallback(personData);
}

// and use that like so:
updatePersonData({name: 'John Doe'}, sendPersonData);

0
投票

我不确定我是否完全了解您需要做什么,但是可以在第一次显示该窗口之前使用ready-to-show事件将数据发送到新窗口。

[如果将数据用于填充现有页面元素,这可能是最有意义的-尽管我想您没有理由不能用新数据炸毁页面上的任何内容-这只是另一个呈现。

加载页面时,当以下情况时,将显示准备就绪事件如果渲染器进程首次将页面渲染窗口尚未显示。

Main.js

mainWindow.once('ready-to-show', () => {
    Menu.setApplicationMenu(basicMenu);

    let data = "some data that have have read from disk and want to send to this new window"
    mainWindow.webContents.send('message', { "event": "data dump", data: data});
    mainWindow.show()
})

Renderer

ipcRenderer.on('message', (event, arg) => {
  switch (arg.event) {
      case "data dump":

       // just a <textArea> but you could do anything with the data.
      $("#dump").text(arg.data);
      break;
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.