无法让我的主进程和渲染器进程在电子中进行通信

问题描述 投票:0回答:1

所以,我对Electron很陌生,想建立一个桌面应用程序。但我一直遇到一些问题,特别是在让渲染器和主进程进行通信方面。我知道IPC和远程的概念,还有这个关于我无法在第一时间使用它们的问题。在决定在这里发帖之前,我试着浏览了很多相关问题。更具体的说,我有一个表单(HTML),需要填写并保存到本地数据库(sqlite)中,我原本计划从HTML中访问数据库,但却无法实现。因此,我去做了一个renderer.js,并把它作为一个脚本包含到HTML中,也失败了(不能使用'require')--在这两次过程中我都打开了nodeintegration。以下是其他的解决方案,目前还没有成功。

  1. 一个preload.js脚本。根据我的想象,我可以在这里包含我的'require'语句,但是当我试图访问DOM元素时,问题就来了,因为我必须注册IPC事件。

  2. 在了解到Browserify工具可以捆绑所有必要的模块,并将其提供给渲染器后,我最终选择了Browserify工具。在这里,我也是按照所述的程序(https:/github.combrowserifybrowserify#usage),但就是无法让它工作,同时又出现了一大堆新的错误(TypeError: fs.exencesSync is not a function, RangeError),而且我仍然在浏览器中得到可怕的'require'is not defined error。

我现在基本上陷入了僵局,不知道该何去何从。如果有必要,我可以在这里分享一些代码。任何帮助都将是非常感激的。

main.js

const MainDAO = require('./dao/appDAO')
const {ipcMain} = require('electron')
const electron = require('electron')
const { app, BrowserWindow, Menu } = require('electron')
const path = require('path')
//const template = require('./js/templates')
//const employeeReg = require('./assets/js/employeeReg')
const dbPath = 'Model/lunaDb'

const dialog = electron.dialog

let lunaDB = new MainDAO(dbPath);
/************************************************************************** */
/*************Login Page
****************************************************************************/
function createSignInWindow() {
  // Create the browser window.
  let signIn = new BrowserWindow({
    width: 800, height: 520, icon: __dirname + '/img/logo.png',
    webPreferences: {
      nodeIntegration: true,
    }
  });
  //Load signin window
  signIn.loadFile('view/signin.html')
  //remove menu list
  signIn.removeMenu();}

注册.html。这是我最初想把表格数据保存到sqlite数据库的地方。

<script src="../dist/bundle.js"></script>
<script>
    var currentTab = 0; // Current tab is set to be the first tab (0)
    showTab(currentTab); // Display the current tab

    function showTab(n) {
        // This function will display the specified tab of the form ...
        var x = document.getElementsByClassName("tab");
        x[n].style.display = "block";
        // ... and fix the Previous/Next buttons:
        if (n == 0) {
            document.getElementById("prevBtn").style.display = "none";
        } else {
            document.getElementById("prevBtn").style.display = "inline";
        }
        if (n == (x.length - 1)) {
            document.getElementById("nextBtn").innerHTML = "Submit And Again";

        } else {
            document.getElementById("nextBtn").innerHTML = "Next";
        }
        // ... and run a function that displays the correct step indicator:
        fixStepIndicator(n)
    }

    function nextPrev(n) {
        // This function will figure out which tab to display
        var x = document.getElementsByClassName("tab");
        // Exit the function if any field in the current tab is invalid:
        if (n == 1 && !validateForm()) return false;
        // Hide the current tab:
        x[currentTab].style.display = "none";
        // Increase or decrease the current tab by 1:
        currentTab = currentTab + n;
        // if you have reached the end of the form... :
        if (currentTab >= x.length) {
            window.location.reload();
            //...the form gets submitted:
            alert("Succesfully Added");
            // document.getElementById("regForm").submit();
            return false;
        }
        // Otherwise, display the correct tab:
        showTab(currentTab);
    }

    function validateForm() {

        // This function deals with validation of the form fields
        var x, y, i, valid = true;
        x = document.getElementsByClassName("tab");
        z = x[currentTab].getElementsByClassName("needs-validation");
        y = x[currentTab].getElementsByTagName("input");
        var validation = Array.prototype.filter.call(z, function (form) {
            form.classList.add("was-validated");

            switch (currentTab) {
                case 0:
                    var name = document.querySelector('#inputName');
                    var email = document.querySelector('#inputEmail');
                    var phone = document.querySelector('#inputPhoneNo')
                    if ((email.checkValidity() == false) || (name.checkValidity() == false) || (name.checkValidity() == false)) {
                        valid = false;
                    }
                    break;

                case 1:
                    var name = document.querySelector('#inputContactName');
                    var phone = document.querySelector('#inputContactPhoneNo');
                    if ((name.checkValidity() == false) || (phone.checkValidity() == false)) {
                        valid = false;
                    }
                    break;
                case 2:
                    var position = document.querySelector('#inputPosition');
                    var salary = document.querySelector('#inputBasicSalary');
                    var hiringDate = document.querySelector('#inputHiringDate')
                    if ((position.checkValidity() == false) || (salary.checkValidity() == false) || (hiringDate.checkValidity() == false)) {
                        valid = false;
                    }
                    break

                default:
                    break;
            }

        });
        if (valid) {
            document.getElementsByClassName("step")[currentTab].className += " finish";
        }
        return valid; // return the valid status
    }

    function fixStepIndicator(n) {
        // This function removes the "active" class of all steps...
        var i, x = document.getElementsByClassName("step");
        for (i = 0; i < x.length; i++) {
            x[i].className = x[i].className.replace(" active", "");
        }
        //... and adds the "active" class to the current step:
        x[n].className += " active";
    }
</script>
<script src="../assets/js/register.js"></script>

register.js(renderer): require没有定义。

const ipc = require('electron').ipcRenderer

const submitEmplForm = document.getElementById('nextBtn')

preload.js : 当我试图访问这里的DOM组件时,它抱怨说是空的,这就是为什么我试图添加require('.register)......那也没有用。

const { ipcRenderer } = require('electron')

const emp = require('./register')

const _setImmediate = setImmediate
const _clearImmediate = clearImmediate
process.once('loaded', () => {
  global.setImmediate = _setImmediate
  global.clearImmediate = _clearImmediate
})

const submitEmplForm = document.querySelector('nextBtn')

submitEmplForm.addEventListener('click', function (event) {
  ipcRenderer.send('asynchronous-message', 'ping')
})

ipcRenderer.on('asynchronous-message', function (event, args) {
  event.preventDefault()
  console.log('event is ' + event)
  console.log(args)
})

当然还有 browserify 的 bundle.js 文件。

javascript node.js electron browserify preload
1个回答
0
投票

仅供参考你是否做了如下的工作 const electron = require('electron');

const {app , BrowserWindow , Menu , ipcMain } = electron; 

/ ipcMain用于通信

let mainWindow;
let addWindow;
app.on('ready', () => {
    mainWindow = new BrowserWindow({webPreferences: {
      nodeIntegration:true}});
    mainWindow.loadURL(`file://${__dirname}/main.html`);
    mainWindow.on('closed', () => app.quit());


    const mainMenu = Menu.buildFromTemplate(menuTemplate);
    Menu.setApplicationMenu(mainMenu);
});

然后在节点侧的ipc main上进行操作

ipcMain.on('todo:add', (event , todo) => {
    console.log(todo);
});

在你的html端

<script>
    const electron = require('electron');
    const {ipcRenderer}= electron; -- to communicate 
    ipcRenderer.on('todo:add', (event , todo) => {
    // my code 
    });
</script>

你有没有做过这样的事情?

你可以分享代码,这将有助于指出其他问题


0
投票

在小心翼翼地创建了一个新文件后,我终于成功地从renderer.js文件中访问了所需的模块和DOM元素,从最基本的开始,逐步添加更多的代码来隔离问题所在。说实话,除了摆脱预加载脚本,再次打开nodeIntegration,以及像我提到的那样,创建一个新的renderer文件,并将其作为脚本链接到HTML之外,我没有做任何不同的事情。这样就成功了,现在主程序和UI可以通过IPC通信了。由于这仅仅是一个桌面应用程序,我希望与开启nodeIntegration相关的任何安全问题都不会有太大问题。

© www.soinside.com 2019 - 2024. All rights reserved.