javascript - tutorial - ¿Cuál es la forma correcta de manejar las formas en Electron?
electron mobile (2)
El formulario html y enviar evento forma parte del "renderizador". Los datos enviados deben estar disponibles en el proceso principal. ¿Cuál es la forma correcta de enviar el formulario y hacer que los datos estén accesibles en main.js?
¿Debería simplemente usar el módulo "remoto" para pasar los datos a una función de main.js o hay un mejor enfoque?
Hay varias variaciones sobre cómo hacer esto, pero todas son a través de IPC .
La IPC (comunicación entre procesos) es la única forma de obtener datos del proceso de procesamiento al proceso principal, y es impulsado por eventos. La forma en que funciona es que puede usar eventos definidos personalizados que el proceso escucha y devuelve algo cuando ocurre ese evento.
El ejemplo declarado por @Adam Eri es una variación del ejemplo de ipcMain que se encuentra en la documentación, pero este método no es de una talla para todos.
El motivo por el que se dice que el asunto puede complicarse rápidamente si está intentando enviar eventos a través del menú (que generalmente se ejecuta en el proceso principal), o a través de componentes a través de un marco frontal como Vue o Angular.
Daré algunos ejemplos:
Usando Remote con WebContents
En su opinión, sí, puede utilizar el remote electrones, pero a los efectos de las formas no es el enfoque recomendado . Basado en la documentación, el punto de control remoto es
Utilizar los módulos de proceso principales del proceso de renderizador.
tl: dr: este proceso puede causar interbloqueos debido a su naturaleza síncrona, puede provocar fugas en los objetos de eventos (debido a la recolección de elementos no utilizados) y genera resultados inesperados con las devoluciones de llamada.
Se puede obtener una explicación adicional a partir de la documentación, pero en última instancia, se establece para utilizar elementos como el dialog
y el menu
en el proceso de procesamiento.
index.js (proceso principal)
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 (Procesar proceso)
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 tradicional
index.js (proceso principal)
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 (Procesar proceso)
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)
}
Usando WebContents
Una tercera opción posible es webContents.executeJavascript para acceder al proceso del renderizador desde el proceso principal. Esta explicación de la sección de documentación remote .
Resumen
Como puede ver, hay algunas opciones sobre cómo manejar formularios con Electron. Mientras uses IPC, deberías estar bien; Es solo la forma en que lo usas lo que te puede meter en problemas. He mostrado opciones simples de javascript para manejar formularios, pero hay innumerables formas de hacerlo. Cuando traes un marco frontal en la mezcla, se vuelve aún más interesante.
Personalmente uso el enfoque tradicional de la CIF cuando puedo.
Espero que te aclare las cosas!
Usamos un servicio (Angular) para procesar los datos del formulario en una ventana. Luego notifique al remote
, si es necesario.
Desde su renderer
puede enviar datos a la ipc
, luego en su main.js
captura este evento y los datos del formulario pasado:
// renderer.js
let ipcRenderer = require(''electron'').ipcRenderer;
ipcRenderer.send(''submitForm'', formData);
// main.js
ipcMain.on(''submitForm'', function(event, data) {
// Access form data here
});
También puede enviar mensajes de vuelta al renderer
desde main.js
O bien sincronizar :
// main.js
ipcMain.on(''submitForm'', function(event, data) {
// Access form data here
event.returnValue = {"any": "value"};
});
O asíncrono :
// 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;
});