无法在我的 node.js 文件 electron 应用程序中使用 HTML ID 和 electron-db

cant use HTML ID in my node.js file electron app with electron-db

你好,我是菜鸟,正在练习后端 我尝试使用 electron 和 electron-db 构建简单的 windwos 应用程序 (https://www.npmjs.com/package/electron-db)

但是当我试图将用户输入保存到数据库行时,我无法将输入 ID 用作插入查询中的值

我的HTML

const db = require("electron-db");
const { app, BrowserWindow } = require("electron");
const mydb = require("./mydb.js");

// db.createTable("medicine", (succ, msg) => {
//   // succ - boolean, tells if the call is successful
//   if (succ) {
//     console.log(msg);
//   } else {
//     console.log("An error has occured. " + msg);
//   }
// });

let obj = new Object();

obj.name = "Alexius Academia";
obj.property = "Paco, Botolan, Zambales";

if (db.valid("medicine")) {
  db.insertTableContent("medicine", obj, (succ, msg) => {
    // succ - boolean, tells if the call is successful
    console.log("Success: " + succ);
    console.log("Message: " + msg);
  });
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>Hello World!</title>
  <link rel="stylesheet" href="index.css" />
</head>

<body>
  <h1>form</h1>
  <form id="contact-form">
    <label for="name">Name</label><br>
    <input type="text" name="name" id="name">
    <br><br>
    <label for="property">Porperty</label><br>
    <input type="text" name="property" id="property">
    <br><br><br>
    <input type="submit" id="submit">
  </form>
  <script>
    let mim = assad;
  document.getElementById("submit").addEventListener("click", function (event) {
      event.preventDefault();
      let name = document.getElementById("name").value;
      let property = document.getElementById("property").value;

      console.log(name);
      console.log(property);
      document.getElementById("contact-form").reset();
    });
  </script>
  <script src="mydb.js"></script>
</body>

</html>

注意到 electron-db 在主线程中使用,您需要将表单数据从渲染线程获取到主线程,您将需要使用一个名为 Inter-Process Communication 的进程。

要安全可靠地执行此操作,您需要熟悉 Context Isolation


好的,让我们一次浏览一个文件...

首先,让我们看一下 html 文件中的代码。

<form> 标签的大部分内容除了提交按钮外看起来都不错。让我们将其更改为 type="button" 因为我们不需要本地“提交”表单,只检测按钮何时被单击。这也允许我们删除代码中更下方的 event.preventDefault(); 行。

现在,让我们向 <script> 标记添加功能,以便它将表单数据发送到主线程。有关这方面的更多信息,请参阅 ipcRender

Note that I have used an IIFE. They can really separate and simplify you code when you have the need to 'instantiate' things. See IIFE for more information.

index.html(渲染线程)

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>Hello World!</title>
  <link rel="stylesheet" href="index.css" />
</head>

<body>
  <h1>form</h1>

  <form id="contact-form">
    <label for="name">Name</label><br>
    <input type="text" name="name" id="name">
    <br><br>
    <label for="property">Property</label><br>
    <input type="text" name="property" id="property">
    <br><br><br>
    <input type="button" id="submit" value="Submit">
  </form>

  <script>
    // IIFE (Immediately Invoked Function Expression).
    (function() => {
        let name = document.getElementById('name').value;
        let property = document.getElementById('property').value;

        document.getElementById("submit").addEventListener('click', submit(name, property))
})();

    // Send the form data back to the main thread.
    function submit(name, property) {
        window.ipcRender.send('contactForm:addData', {
            "name": name,
            "property": property
        });

        // Reset the form (if needed).
        document.getElementById('contact-form').reset();
    }
  </script>

  <script src="mydb.js"></script>
</body>

允许白名单通道在主线程和渲染线程之间进行通信的 'glue' 调用 preload 脚本。它在您的 window 的构建过程中被调用。这里我们加一个'channel name'来标识,这样就可以通过

Notice that I used a name:function format so it clearly defines the channel. Useful when you have a lot of channels.

preload.js(主线程)

const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;

// White-listed channels.
const ipc = {
    'render': {
        // From render to main.
        'send': [
            'contactForm:addData'
        ],
        // From main to render.
        'receive': [],
        // From render to main and back again.
        'sendReceive': []
    }
};

contextBridge.exposeInMainWorld(
    // Allowed 'ipcRenderer' methods.
    'ipcRender', {
        // From render to main.
        send: (channel, args) => {
            let validChannels = ipc.render.send;
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, args);
            }
        },
        // From main to render.
        receive: (channel, listener) => {
            let validChannels = ipc.render.receive;
            if (validChannels.includes(channel)) {
                // Deliberately strip event as it includes `sender`
                ipcRenderer.on(channel, (event, ...args) => listener(...args));
            }
        },
        // From render to main and back again.
        invoke: (channel, args) => {
            let validChannels = ipc.render.sendReceive;
            if (validChannels.includes(channel)) {
                return ipcRenderer.invoke(channel, args);
            }
        }
    }
);

最后,在您正在进行所有工作的主线程中的文件中,您需要留意并留意 IPC 频道上的广播。

首先,让我们添加 Electron 模块 ipcMain 和其他模块。

然后,使用 IIFE,留意该频道的广播。如果通道被调用,调用 addContactData 函数与通信 data 对象插入到数据库中。

(主线程)

const db = require("electron-db");
const { app, BrowserWindow, ipcMain } = require("electron");
const mydb = require("./mydb.js");

// IIFE (Immediately Invoked Function Expression)
(function() => {
    ipcMain.on('contactForm:addData', (event, data) => { addContactData(data); });
})();

// db.createTable("medicine", (succ, msg) => {
//   // succ - boolean, tells if the call is successful
//   if (succ) {
//     console.log(msg);
//   } else {
//     console.log("An error has occured. " + msg);
//   }
// });

// let obj = new Object();
// obj.name = "Alexius Academia";
// obj.property = "Paco, Botolan, Zambales";

function addContactData(data) {
    if (db.valid("medicine")) {
        db.insertTableContent("medicine", data, (succ, msg) => {
        // succ - boolean, tells if the call is successful
        console.log("Success: " + succ);
        console.log("Message: " + msg);
    });
}