Вызов объекта в main.js из модуля в Electron - PullRequest
0 голосов
/ 03 мая 2018

У меня есть приложение Electron с 2 модулями, один из которых является стандартным меню. Когда я щелкаю пункт меню, я хочу, чтобы он вызывал функцию экземпляра модуля.

Единственное решение, которое я нашел, это чтобы мой экземплярный объект являлся свойством основного electron.app объекта, который доступен глобально.

Вот мой пример:

main.js

const electron = require('electron');
const app = electron.app;

const WindowManager = require('components/WindowManager');
let windowManager = new WindowManager(); // <- I want my menu item to call a function from this object

const MainMenu = require('components/MainMenu');
let mainMenu = new MainMenu();

function initApp() {
    let menuTemplate = mainMenu.getTemplate();        
    let menuBuilt = electron.Menu.buildFromTemplate(menuTemplate);
    electron.Menu.setApplicationMenu(menuBuilt);
}

function mainTestFileOpen() {
    console.log('File open test function in main.js');
}

// I'm trying to avoid doing this
app.testFileOpen = function() {
    console.log('Function is part of "app" so globally accessible...');
}

// I'm trying to avoid doing this too
app.appWindowManager = new WindowManager();

// Start the app
app.on('ready', initApp);

компоненты / WindowManager.js

class WindowManager {
    constructor() {
        this.doFileOpen = this.doFileOpen.bind(this);
    }

    doFileOpen() {
        console.log('File open from WinwdowManager module');
    }
}
module.exports = WindowManager;

компоненты / MainMenu.js

const electron = require('electron');
class MainMenu {
    constructor() {
        this.template = [];

        this.init = this.init.bind(this);
        this.getTemplate = this.getTemplate.bind(this);

        // Initialize
        this.init();
    }

    getTemplate() {
        return this.template;
    }

    init() {
        this.template = [{
            label: 'File',
            submenu: [{
                label: "Open File",
                click() {
                    /** Calling a function in main.js does NOT work **/
                    mainTestFileOpen();

                    /** Calling an object in main.js doe NOT work **/
                    windowManager.doFileOpen();

                    /** If the function is part of "app" then it works **/
                    electron.app.testFileOpen();

                    /** If the instantiated object is part of "app" then it works  **/
                    electron.app.appWindowManager.doFileOpen();
                }
            }]
        }]
    }
}

module.exports = MainMenu;

Я думаю, что я не получаю область действия click() в шаблоне электронного меню.

1 Ответ

0 голосов
/ 04 мая 2018

Вы пытаетесь вызвать функцию из другого модуля (каждый файл в Node - это собственный модуль, который отличается от типичной среды JS) без предварительного импорта модуля.

Недостаточно просто написать функцию в модуле main.js:

function mainTestFileOpen() {
    console.log('File open test function in main.js');
}

И ожидайте вызвать его из модуля MainMenu.js. Сначала вы должны export это:

export function mainTestFileOpen() { ... }

Затем в MainMenu.js вы можете импортировать его вверху:

import { mainTestFileOpen } from "../main";

То же самое с windowManager. Не похоже, что вы что-то делаете с WindowManager из main.js, поэтому просто перенесите импорт и создание экземпляров в MainMenu.js:

import { WindowManager } from "./WindowManager";
let windowManager = new WindowManager();

И тогда вы сможете сделать:

windowManager.doFileOpen();

Примечание:

Вы делаете такие вещи в конструкторе: this.doFileOpen = this.doFileOpen.bind(this);

В этом нет необходимости, поскольку единственный способ вызвать doFileOpen - это вызвать его на экземпляре windowManager следующим образом: windowManager.doFileOpen(...).

То же самое относится к:

this.init = this.init.bind(this);
this.getTemplate = this.getTemplate.bind(this);
...