表单html和submit事件是"渲染器"的一部分。 提交的数据应在主要流程中提供。 在main.js中提交表单并使数据可访问的正确方法是什么?
我应该只使用"遥控器"模块将数据传递给main.js中的函数,还是有更好的方法?
答案 0 :(得分:11)
我们使用服务(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;
});
答案 1 :(得分:7)
如何执行此操作有多种变体,但所有变体都来自IPC。
IPC(进程间通信)是将数据从渲染过程提取到主进程的唯一方法,并且是事件驱动的。它的工作方式是您可以使用进程侦听的自定义事件,并在事件发生时返回一些事件。
@Adam Eri所述的示例是文档中找到的ipcMain example的变体,但这种方法并非一刀切。
如果您尝试通过菜单(通常在主进程上运行)或通过Vue或Angular等前端框架通过组件发送事件,说明问题的原因很快就会变得复杂。
我将举几个例子:
使用远程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方法。
希望能为你解决问题!
答案 2 :(得分:0)
远程是共享数据的好方法。使用全局变量并将其与电子应用程序的其他页面共享。因此,基于以下IPC方法,我能够通过这种方式进行管理:
1)将此代码添加到main.js文件中:
global.MyGlobalObject = {
variable_1: '12345'
}
2)在第一页上使用它来更新全局变量值:
require('electron').remote.getGlobal('MyGlobalObject').variable_1= '4567'
3)最后,在第二页上使用类似的内容,在该页面上,您将访问修改后的全局变量并进行打印:
console.log(require('electron').remote.getGlobal('MyGlobalObject').variable_1)
您可以在电子的documentation中找到相同的东西。