2017-04-09 56 views
16

Forma html i submit event jest częścią "renderer". Przesłane dane powinny być dostępne w procesie głównym. Jaki jest właściwy sposób przesłania formularza i udostępnienia tych danych w pliku main.js?Jaki jest właściwy sposób obsługi formularzy w Electron?

Czy powinienem po prostu użyć modułu "zdalnego" do przekazania danych do funkcji z main.js lub czy istnieje lepsze podejście?

+0

Czy pytasz z punktu widzenia ramy czołowej, czy czysto elektronowo? –

Odpowiedz

7

Używamy usługi (kątowej) do przetwarzania danych formularza w oknie. Następnie w razie potrzeby powiadom o tym numer remote.


z Twojego renderer można wysyłać dane do ipc, następnie w swojej main.js złapiesz to zdarzenie i przekazywane dane formularza:

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

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

Można również wysyłać wiadomości z powrotem do renderer z main.js.

Albo sync:

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

Albo asynchroniczny:

// 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; 
}); 
3

Istnieje kilka wariacji na temat, jak to zrobić, ale wszystkie są poprzez IPC.

IPC (komunikacja między procesami) to jedyny sposób na uzyskanie danych z procesu renderowania do głównego procesu i jest sterowany zdarzeniami. Działa to w taki sposób, że można używać niestandardowych zdefiniowanych zdarzeń, które proces nasłuchuje i zwraca coś, gdy zdarzenie to się wydarzy.

Przykład podany przez @Adam Eri jest odmianą w ipcMain example znalezioną w dokumentacji, ale ta metoda nie jest uniwersalna dla wszystkich.

Powód mówienia, że ​​to jest sprawa, może szybko stać się skomplikowany, jeśli próbujesz wysyłać zdarzenia za pośrednictwem menu (które zazwyczaj działa w głównym procesie) lub przez komponenty za pośrednictwem frontowej struktury, takiej jak Vue lub Angular.

Podam kilka przykładów:

Korzystanie ze zdalnych z WebContents

do punktu, tak można użyć elektron remote, ale dla celów form nie jest to zalecane podejście . Na podstawie dokumentacji, punkt pilota jest

używać modułów głównego procesu z procesu renderer

tl: dr -To proces może powodować zakleszczenia ze względu na jego charakter synchroniczny, może powodować obiekt zdarzenia wycieki (ze względu na odśmiecanie) i prowadzi do nieoczekiwanych wyników z oddzwanianiem.

Dalsze wyjaśnienia można uzyskać z dokumentacji, ale ostatecznie jest to ustawione do używania elementów takich jak dialog i menu w procesie renderowania.

index.js (proces główny)

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 (wykonywali Proces)

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 
    */ 
}); 

tradycyjne IPC

index.js (główny proces)

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 (wykonywali Proces)

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

Korzystanie WebContents

Możliwym trzecia opcja to webContents.executeJavascript, aby uzyskać dostęp do procesu renderowania z głównego procesu. To wyjaśnienie z sekcji dokumentacji remote.

Podsumowanie

Jak widać, istnieje kilka opcji, w jaki sposób obsługiwać formularze z elektron. Dopóki używasz IPC, powinieneś być w porządku; to, jak go używasz, może wpędzić cię w kłopoty. Pokazałem proste opcje obsługi javascript do obsługi formularzy, ale istnieją niezliczone sposoby, aby to zrobić. Kiedy wprowadzisz strukturę front-end do miksu, staje się jeszcze bardziej interesujący.

Ja osobiście używam tradycyjnego podejścia do IPC, kiedy mogę.

Mam nadzieję, że wszystko wyjaśnisz!

+1

Nadal nie jest jasne, dlaczego tradycyjny sposób IPC nie jest zalecany zgodnie z tobą. Co się stanie, jeśli nie użyję żadnych struktur, takich jak kątowe? – JerryGoyal

+0

Jeśli przeczytasz powyższe podsumowanie, będzie dla ciebie bardziej zrozumiałe. Nie polecam niczego poza tradycyjnym IPC (musisz mieć tę odpowiedź zdezorientowaną z powyższą kopią Adama). Podam przykład, jak to zrobić bez frameworka –