Как правильно передать некоторые начальные данные в новое окно? - PullRequest
0 голосов
/ 23 февраля 2020

Я только изучаю Electron и пытаюсь открыть файл и отобразить его в новом окне. Я нажимаю кнопку в начальном (root) окне, которое затем открывает диалоговое окно «Открыть файл», из которого я могу получить путь к файлу. Я хотел бы затем открыть этот файл, создать окно и передать содержимое файла в новое окно. Моя проблема заключается в получении строки с содержимым файла в функцию обратного вызова, когда окно готово; это вообще возможно? Мой главный. 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

Ответы [ 2 ]

0 голосов
/ 23 февраля 2020

Способ webContents должен легко решить вашу проблему. Это просто: вы заранее создаете и собираете все данные, которые нужны окну, а затем порождаете окно с этим.

Существует несколько ограничений в способе webContents, потому что объект webContents, который вы создаете на main сериализуется и отправляется на render - это означает, что оба процесса имеют независимые версии объекта:

  1. Изменения, примененные к объекту в версии процесса визуализации, ваших данных не будут отражены в main (и наоборот)
  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 голосов
/ 23 февраля 2020

Я не уверен, что полностью понимаю, что вам нужно сделать, но вы можете использовать событие ready-to-show , чтобы отправить данные в новое окно до того, как оно будет показано в первый раз.

Это, вероятно, наиболее целесообразно, если данные используются для заполнения существующих элементов страницы - хотя я полагаю, что нет причин, по которым вы не можете выбросить то, что было на странице, новыми данными - это просто еще один render.

При загрузке страницы событие готовности к показу будет отправлено, когда процесс рендеринга впервые отобразит страницу, если окно еще не было отображено.

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;
  }
});
...