Каков правильный способ обработки форм в Electron?

Форма html и отправить событие является частью "средства визуализации". Представленные данные должны быть доступны в основном процессе. Каким образом можно отправить форму и сделать эти данные доступными в main.js?

Должен ли я просто использовать модуль "remote" для передачи данных функции из main.js или есть лучший подход?

Ответы

Ответ 1

Мы используем службу (Angular) для обработки данных формы в окне. Затем сообщите remote, если необходимо.


Из вашего renderer вы можете отправить данные в ipc, а затем в main.js вы поймаете это событие и переданные данные формы:

// renderer.js
let ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.send('submitForm', formData);

// main.js
ipcMain.on('submitForm', function(event, data) {
   // Access form data here
});

Вы также можете отправить сообщения обратно в renderer из main.js.

Либо синхронизация:

// main.js
ipcMain.on('submitForm', function(event, data) {
   // Access form data here
   event.returnValue = {"any": "value"};
});

Или async:

// main.js
ipcMain.on('submitForm', function(event, data) {
   // Access form data here
   event.sender.send('formSubmissionResults', results);
});

// renderer.js
ipcRenderer.on('formSubmissionResults', function(event, args) {
   let results = args.body;
});

Ответ 2

Существует несколько вариантов того, как это сделать, но все это через IPC.

IPC (межпроцессное общение) - это единственный способ получить данные из процесса визуализации в основной процесс и управляться событиями. Как это работает, вы можете использовать настраиваемые события, которые процесс прослушивает и возвращает что-то, когда это событие происходит.

Пример, описанный @Adam Eri, представляет собой вариант на пример ipcMain, найденный в документации, но этот метод не подходит для одного размера все.

Причина того, что это так, может быстро усложниться, если вы пытаетесь отправить события через меню (которое обычно выполняется в основном процессе) или через компоненты с помощью интерфейсного интерфейса, такого как Vue или Angular.

Я приведу несколько примеров:

Использование Remote с WebContents

К вашему моменту, да, вы можете использовать электрон remote, но для целей форм это не рекомендуется подход. Основываясь на документации, точка удаленного находится в

Использовать основные процессы из процесса рендеринга

tl: dr -Этот процесс может вызвать взаимоблокировки из-за его синхронного характера, может вызвать утечку объектов объекта (из-за сбора мусора) и приводит к неожиданным результатам с обратными вызовами.

Дальнейшее объяснение может быть получено из документации, но в конечном итоге это устанавливается для использования таких элементов, как dialog и menu в процессе рендеринга.

index.js(основной процесс)

const { app, BrowserWindow, ipcMain } = require('electron');
const path = require ('path');
const fs = require('fs');
const os = require('os');

let window;

function createWindow(){
    window = new BrowserWindow({
        show: false
    });

    window.loadURL(`file://${__dirname}/index.html`);
    window.once('ready-to-show', function (){
        window.show();
    });

    window.webContents.openDevTools();

    let contents = window.webContents;

    window.on('closed', function() {
        window = null;
    });
}

exports.handleForm = function handleForm(targetWindow, firstname) {
    console.log("this is the firstname from the form ->", firstname)
    targetWindow.webContents.send('form-received', "we got it");
};

app.on('ready', function(){
    createWindow();
});

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Electron App</title>
    </head>

    <body>

        <form action="#" id="ipcForm2">
            First name:<br>
            <input type="text" name="firstname" id="firstname" value="John">
            <br>
            Last name:<br>
            <input type="text" name="lastname" id="lastname" value="Smith">
            <br><br>
            <input id="submit" type="submit" value="submit">
        </form>

        <p id="response"></p>

        <script src='renderFile.js'></script>
    </body>
</html>

renderFile.js(процесс рендеринга)

const { remote, ipcRenderer } = require('electron');
const { handleForm} = remote.require('./index');
const currentWindow = remote.getCurrentWindow();

const submitFormButton = document.querySelector("#ipcForm2");
const responseParagraph = document.getElementById('response')

submitFormButton.addEventListener("submit", function(event){
        event.preventDefault();   // stop the form from submitting
        let firstname = document.getElementById("firstname").value;
        handleForm(currentWindow, firstname)
});

ipcRenderer.on('form-received', function(event, args){
    responseParagraph.innerHTML = args
    /*
        you could choose to submit the form here after the main process completes
        and use this as a processing step
    */
});

Традиционный IPC

index.js(Основной процесс)

const { app, BrowserWindow, ipcMain } = require('electron');
const path = require ('path');
const fs = require('fs');
const os = require('os');

let window;

function createWindow(){
    window = new BrowserWindow({
        show: false
    });

    window.loadURL(`file://${__dirname}/index.html`);
    window.once('ready-to-show', function (){
        window.show();
    });

    window.webContents.openDevTools();

    let contents = window.webContents;

    window.on('closed', function() {
        window = null;
    });
}

ipcMain.on('form-submission', function (event, firstname) {
    console.log("this is the firstname from the form ->", firstname)
});

app.on('ready', function(){
    createWindow();
});

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Electron App</title>
    </head>

    <body>

        <form name="ipcForm" onSubmit="JavaScript:sendForm(event)">
            First name:<br>
            <input type="text" name="firstname" id="firstname" value="John">
            <br>
            Last name:<br>
            <input type="text" name="lastname" id="lastname" value="Smith">
            <br><br>
            <input type="submit" value="Submit">
        </form>

        <script src='renderFile.js'></script>
    </body>
</html>

renderFile.js(процесс рендеринга)

const ipcRenderer = require('electron').ipcRenderer;

function sendForm(event) {
    event.preventDefault() // stop the form from submitting
    let firstname = document.getElementById("firstname").value;
    ipcRenderer.send('form-submission', firstname)
}

Использование WebContents

Возможным третьим вариантом является webContents.executeJavascript для доступа к процессу рендеринга из основного процесса. Это объяснение из раздела документации remote.

Резюме

Как вы можете видеть, существует несколько вариантов управления формами с помощью Electron. До тех пор, пока вы используете IPC, вы должны быть в порядке; его просто как вы его используете, что может вызвать у вас неприятности. Я показал простые параметры javascript для обработки форм, но есть множество способов сделать это. Когда вы добавляете фреймворк в микс, он становится еще интереснее.

Я лично использую традиционный подход IPC, когда могу.

Надеюсь, что это очистит вас!