从Electron中的模块调用main.js中的对象

时间:2018-05-03 20:50:22

标签: javascript class module electron

我有一个带有2个模块的Electron应用程序,其中一个是标准菜单。当我单击一个菜单项时,我希望它调用一个实例化模块的功能。

我发现的唯一解决方案是让我的实例化对象成为主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 :(得分:1)

您正在尝试从不同的模块调用函数(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相同。它看起来好像你正在使用main.js中的WindowManager做任何事情,所以只需将导入和实例化移动到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);