在Electron中处理表单的正确方法是什么?
表单html和提交事件是“渲染器”的一部分。 提交的数据应在主stream程中提供。 提交表单并在main.js中访问数据的正确方法是什么?
我应该简单地使用“远程”模块将数据从main.js传递给函数吗?还是有更好的方法?
我们使用一个服务(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 });
您也可以通过main.js
将消息发送回renderer
。
要么同步 :
// main.js ipcMain.on('submitForm', function(event, data) { // Access form data here event.returnValue = {"any": "value"}; });
或asynchronous :
// 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; });
如何做到这一点有几个变化,但都是通过IPC 。
IPC(进程间通信)是从渲染进程到主进程获取数据的唯一方式,并且是事件驱动的。 这种方式的工作原理是,您可以使用自定义的事件进程侦听并返回一些事件发生时。
@Adam Eri指出的例子是在文档中find的ipcMain例子的一个变种,但是这种方法并不是一成不变的 。
如果您试图通过菜单(通常在主进程上运行)发送事件,或者通过前端框架(如Vue或Angular)发送事件,则说明这一点的原因可能会很快变得复杂。
我将举几个例子:
与WebContents一起使用远程
就你而言,是的,你可以使用电子遥控器 ,但为了forms的目的, 这不是推荐的方法 。 基于文档,远程的意义在于
使用渲染器进程中的主要进程模块
tl:dr – 此进程由于其同步特性可能导致死锁,可能导致事件对象泄漏(由于垃圾回收),并导致带callback的意外结果。
从文档可以得到进一步的解释,但最终这是设置为在渲染过程中使用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(主stream程)
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从主进程访问渲染器进程。 这从远程文档部分的解释。
概要
正如你所看到的,关于如何用Electron处理表单有几个选项。 只要你使用IPC,你应该没问题; 它只是如何使用它可以让你陷入困境。 我已经显示了处理表单的简单的JavaScript选项,但是有无数的方法可以这样做。 当你将前端框架融合到一起时,它会变得更有趣。
我个人使用传统的IPC方法。
希望能为你解决问题!