Можно ли вызвать код Ionic 4 / Capacitor Electron из части приложения Ionic?
Я исследую использование Ionic 4/ Capacitor для целевой Windows с помощью опции Electron, для приложения, в котором я хочу использовать SQLite.
Насколько я вижу, с помощью плагина Ionic Native SQLite, который упаковывает этот плагин Cordova, "из коробки" поддерживается Windows, а не Desktop, который работает с использованием Electron в оболочке Ionic Capacitor.
Мой план состоял в том, чтобы посмотреть, смогу ли я использовать пакет Electron SQLite, а затем вызвать его из моего Ionic-приложения, создав класс-оболочку для Ionic- натива, аналогичный тому, который я использовал для получения поддержки браузера, следуя этому наставлению.
Если я могу вызвать код Electron из моего приложения Ionic, то я не могу понять, почему это не сработает.
Итак, мой вопрос здесь, могу ли я вызвать код (я добавлю функции для использования SQlite), который я добавляю в приложение Electron хостинга из Ионического (веб) кода? И если да, то как?
Заранее благодарю за любую помощь
[Update1]
Попробовал следующее...
Со страницы Ionic у меня есть обработчик нажатия кнопки, где я поднимаю событие..
export class HomePage {
public devtools() : void {
let emit = new EventEmitter(true);
emit.emit('myEvent');
var evt = new CustomEvent('myEvent');
window.dispatchEvent(evt);
}
Затем в рамках проектов "Электрон" index.js
, Я старался..
mainWindow.webContents.on('myEvent', () => {
mainWindow.openDevTools();
});
const ipc = require('electron').ipcMain
ipc.on('myEvent', (ev, arg) => {
mainWindow.openDevTools();
});
Но ни один не работал.
Я должен отметить, что я знаю очень мало об Electron. Это мое первое знакомство с ним (через конденсатор)
1 ответ
Если кому-то интересно, вот как я это решил. Я использую Ionic 4 / Capacitor + Vue 3.
В моем входном файле (app.ts) я объявил глобальный интерфейс под названием Window следующим образом:
// app.ts
declare global { interface Window { require: any; } }
Затем я написал следующий класс:
// electron.ts
import { isPlatform } from '@ionic/core';
export class Electron
{
public static isElectron = isPlatform(window, 'electron');
public static getElectron()
{
if (this.isElectron)
{
return window.require('electron');
}
else
{
return null;
}
}
public static getIpcRenderer()
{
if (this.isElectron)
{
return window.require('electron').ipcRenderer;
}
else
{
return null;
}
}
public static getOs()
{
if (this.isElectron)
{
return window.require('os');
}
else
{
return null;
}
}
}
И использую это так:
//electronabout.ts
import { IAbout } from './iabout';
import { Plugins } from '@capacitor/core';
import { Electron } from '../utils/electron';
export class ElectronAbout implements IAbout
{
constructor() { }
public async getDeviceInfo()
{
let os = Electron.getOs();
let devInfo =
{
arch: os.arch(),
platform: os.platform(),
type: os.type(),
userInfo: os.userInfo()
};
return devInfo;
}
public async showDeviceInfo()
{
const devInfo = await this.getDeviceInfo();
await Plugins.Modals.alert({ title: 'Info from Electron', message: JSON.stringify(devInfo) });
}
}
Это работает, но, конечно, мне все еще нужно реорганизовать класс Electron (electronic.ts). Вероятно, использование шаблона singleton - лучшая идея.
Надеюсь, это поможет.
Обновить
Вы можете общаться из процесса рендеринга с вашим основным процессом (index.js) следующим образом:
//somefile.ts
if (Electron.isElectron)
{
let ipc = Electron.getIpcRenderer();
ipc.once('hide-menu-button', (event) => { this.isMenuButtonVisible = false; });
}
//index.js
let newWindow = new BrowserWindow(windowOptions);
newWindow.loadURL(`file://${__dirname}/app/index.html`);
newWindow.webContents.on('dom-ready', () => {
newWindow.webContents.send('hide-menu-button');
newWindow.show();
});
Да, ты можешь! Помните, электрон использует хром, и у вас есть поддержка
Вчера я углубился в это и у вас есть пример использования angular(это должно относиться и к ionic). в вашей службе объявите требование, чтобы мы могли его использовать
//Below your imports
declare function require(name:string);
Затем в любой функции, в которой вы хотите его использовать:
// Require the ipcRenderer so we can emit to the ipc to call a function
// Use ts-ignore or else angular wont compile
// @ts-ignore
const ipc = window.require('electron').ipcRenderer;
// Send a message to the ipc
// @ts-ignore
ipc.send('test', 'google');
Затем в созданном index.js в электронной папке
// Listening for the emitted event
ipc.addListener('test', (ev, arg) => {
// console.log('ev', ev);
console.log('arg', arg);
});
Вероятно, это не правильный способ получить к нему доступ, но это лучший способ, который я мог найти. Насколько я понимаю, ipcRenderer используется, когда у вас есть несколько браузеров, которые общаются друг с другом в электроне. поэтому в нашей ситуации это позволяет нашему веб-слою связываться с электронным материалом