随着第一章中构建的应用程序,我们将开始将其与Electron框架中的模块集成,并以此为基础,以更实用的方式了解它们。
过程之间的通信
根据第二章中的解释,我们将发送每个进程之间的消息;具体来说联系人和聊天;这些数据将在主过程中定义,因为这是负责处理这些数据的过程我们之前已经将其与中使用的客户端-服务器体系结构进行了比较web编程,主要过程已经是服务器和网页一直是客户端,它是从我们可以管理所有这些数据,正如我们将在整本书中看到的那样第一次联系,我们将了解如何从主进程处理到网页。
上传联系人和聊天
为了传递主流程中定义的数据,我们将使用以下结构;数据将从主进程中获得,为了模拟数据库等外部结构,我们将创建一个单独的文件到index.js,该文件将负责提供数据,我们将使用数据创建几个模块,使其易于使用:data.js
const contacts = [
{
name: "Alex Alexis",
image: "https://randomuser.me/api/portraits/women/56.jpg",
last_chat: [
{
date: "9:15 AM",
message: "Lorem ipsum dolor sit amet",
},
],
},
{
name: "Eli Barrett",
image: "https://randomuser.me/api/portraits/women/96.jpg",
last_chat: [
{
date: "8:30 PM",
message: "Lorem ipsum dolor sit amet",
},
],
},
{
name: "Kylie Young",
image: "https://randomuser.me/api/portraits/women/45.jpg",
last_chat: [
{
date: "8:30 PM",
message: "Lorem ipsum dolor sit amet",
},
],
},
{
name: "Kylie Young",
image: "https://randomuser.me/api/portraits/women/45.jpg",
last_chat: [
{
date: "8:30 PM",
message: "Lorem ipsum dolor sit amet",
},
],
},
];
const chats = [
{
user: {
name: "Alex Alexis",
image: "https://randomuser.me/api/portraits/women/56.jpg",
},
chat: {
date: "9:15 AM",
message:
"Lorem ipsum dolor sit amet consectetur adipisicing elit.Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",
},
},
{
user: {
name: "Eli Barrett",
image: "https://randomuser.me/api/portraits/women/58.jpg",
},
chat: {
date: "9:50 AM",
message:
"Lorem ipsum dolor sit amet consectetur adipisicing elit.Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",
},
},
];
module.exports.contacts = contacts;
module.exports.chats = chats;
从“index.js”,我们激活与Node的集成并消费它们;我们定义了一个事件,在该事件中,当通过“did-finish-load”事件加载窗口(网页)时,我们通过消息传输数据:
const { app, BrowserWindow, Menu, shell } = require("electron");
const { chats, contacts } = require("./data");
function createWindow() {
let win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
});
win.loadFile("index.html");
win.webContents.openDevTools();
win.webContents.on("did-finish-load", () => {
win.webContents.send("pr-chats", chats);
win.webContents.send("pr-contacts", contacts);
});
}
app.whenReady().then(createWindow);
从网页上,由于我们激活了与Node的集成,我们可以导入ipcRenderer模块,以便能够与主进程通信,特别是,我们有兴趣创建一个侦听器来接收主进程发送的数据:
index.html
<script>
function createChats(chats) {
var lis = ''
chats.forEach((c) => {
lis += ` <div class="d-flex chat">
<div class="w-75 ">
<div class="card bg-dark">
<div class="card-body text-light">
${c.chat.message}
</div>
</div>
<p class="small text-muted float-end">${c.chat.date}</p>
</div>
<div class="w-25 d-flex align-items-end">
<img class="rounded-pill ms-3 avatar" src="${c.user.image}"/>
</div>
</div>`
})
document.querySelector('.chats').innerHTML = lis;
}
function createContacts(contacts) {
var lis = ''
contacts.forEach((c) => {
lis += `<li class="p-2 card mt-2">
<div class="card-body">
<div class="d-flex">
<div>
<img class="rounded-pill me-3" width="60"
src="${c.image}">
</div>
<div>
<p class="fw-bold mb-0 text-light">${c.name}</p>
<p class="small text-muted">${c.last_chat[0]['message']}
</p>
</div>
<div>
<p class="small text-muted">${c.last_chat[0]['date']}</p>
<span class="badge bg-danger rounded-pill float-end">1</span>
</div>
</div>
</div>
</li>`
})
document.querySelector('.contact').innerHTML = lis;
}
const { ipcRenderer } = require('electron')
ipcRenderer.on('pr-chats', (event, chats) => {
createChats(chats)
})
ipcRenderer.on('pr-contacts', (event, contacts) => {
createContacts(contacts)
})
</script>
根据具体情况,我们稍微更改函数的签名,在该签名中,我们接收图表或联系人作为参数。我们调用这些函数来从先前定义的侦听器构建列表;最后,我们将得到相同的结果,但现在数据从主进程进入渲染进程。
按选择加载联系人
在本节中,我们将实现以下功能:通过单击其中一个联系人,加载与所述联系人对应的聊天或消息;为了模拟这种行为,我们将使用联系人数组索引,就好像它是我们有兴趣获得聊天记录的联系人的ID一样;为此,我们实现了一个点击事件:
以及函数,我们调用主进程来提供基于ID的聊天:
function changeContact(index) {
ipcRenderer.send('pp-get-chat', index)
}
在数据拉取中,我们将稍微改变结构,我们将有一个数组,其中数组的每个位置都将由上一条消息中提供的联系人索引访问:
const contacts = [
{
name: "Alex Alexis",
image: "https://randomuser.me/api/portraits/women/56.jpg",
last_chat: [
{
date: "9:15 AM",
message: "Lorem ipsum dolor sit amet consectetur adipisicing elit",
},
],
},
{
name: "Ramon Reed",
image: "https://randomuser.me/api/portraits/women/59.jpg",
last_chat: [
{
date: "9:15 AM",
message: "Lorem Hello!",
},
],
},
{
name: "Eli Barrett",
image: "https://randomuser.me/api/portraits/women/58.jpg",
last_chat: [
{
date: "8:55 PM",
message: "Lorem ipsum dolor sit ...",
},
],
},
];
const chats = [
[
{
user: {
name: "Alex Alexis",
image: "https://randomuser.me/api/portraits/women/56.jpg",
},
chat: {
date: "9:15 AM",
message:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",
},
},
{
user: {
name: "Luis Perez",
image: "https://randomuser.me/api/portraits/women/58.jpg",
},
chat: {
date: "9:50 AM",
message:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",
},
},
],
[],
[
{
user: {
name: "Anselmo Perez",
image: "https://randomuser.me/api/portraits/women/1.jpg",
},
chat: {
date: "10:45 PM",
message:
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus reprehenderit voluptatibus cumque, deserunt deleniti consequatur adipisci nisi consequuntur sunt itaque? Sunt aspernatur, ratione labore ipsam enim unde itaque dolorum magni?",
},
},
],
];
module.exports.contacts = contacts;
module.exports.chats = chats;
我们实现了从ipcRenderer发送的事件,其中,将接收到的索引作为参数,返回相应的聊天:
index.js
const { ipcMain } = require("electron");
win.webContents.on("did-finish-load", () => {
//win.webContents.send("pr-chats", chats);
win.webContents.send("pr-contacts", contacts);
});
ipcMain.on('pp-get-chat', (event, index) => {
win.webContents.send('pr-chats', chats[index])
})
当所选联系人没有聊天时,我们还会显示一个默认窗口:
function createChats(chats) {
var lis = ''
if (chats.length == 0) {
lis += ` <div class="d-flex chat">
<div class="w-75 ">
<div class="card bg-dark">
<div class="card-body text-light">
<h3 class='text-center'>No message</h3>
</div>
</div>
</div>
</div>`
}
else {
chats.forEach((c) => {
lis += ` <div class="d-flex chat">
<div class="w-75 ">
<div class="card bg-dark">
<div class="card-body text-light">
${c.chat.message}
</div>
</div>
<p class="small text-muted float-end">${c.chat.date}</p>
</div>
<div class="w-25 d-flex align-items-end">
<img class="rounded-pill ms-3 avatar" src="${c.user.image}"/>
</div>
</div>`
})
}
document.querySelector('.chats').innerHTML = lis;
}
这样,在选择联系人时,我们会改变显示的消息或聊天,并完成骨架应用程序;您可以在以下位置找到源代码:
https://github.com/libredesarrollo/electron-chat-app/releases/tag/v0.1