electron TypeError:无法读取未定义的属性(阅读'model')

mepcadol  于 2022-12-08  发布在  Electron
关注(0)|答案(1)|浏览(300)

我是Javascript和Typescript的新手,我正在开发一个电子应用程序作为一个副项目。我遇到这个错误,它可能与函数作用域有关,但我似乎不明白。有人能给我解释一下这个行为,并给予我一个如何处理这个问题的建议吗?以下是我的模块文件:

主要.ts:

/*
* Implementation of main module.
*/

import { app, BrowserWindow, ipcMain, dialog } from 'electron';
import path from 'path';
import Controller from './controller/controller';
import Model from './model/model';

class Main {
  controller: Controller;
  mainWindow: BrowserWindow | undefined;
  application: Electron.App;

  constructor(application: Electron.App, controller: Controller) {
    this.controller = controller;
    this.application = application;
  }

  openMessageBox(_event: Event, message: string) {
    const options = {
      title: 'Unable to start scanning',
      message,
    };
    if (!this.mainWindow) {
      return;
    }
    dialog.showMessageBox(this.mainWindow, options);
  }

  addHandlers() {
    ipcMain.handle('getNetworkInterfaceControllers', this.controller.getNetworkInterfaceControllers);
    ipcMain.handle('setInterfaceSelection', this.controller.setInterfaceSelection);
    ipcMain.handle('setInterfaceMac', this.controller.setInterfaceMac);
    ipcMain.handle('setBandSelection', this.controller.setBandSelection);
    ipcMain.handle('startScanning', this.controller.model.scanAccessPoints);
    ipcMain.handle('getAccessPoints', this.controller.getAccessPoints);
    ipcMain.handle('openMessageBox', this.openMessageBox);
  }

  createWindow() {
    this.mainWindow = new BrowserWindow(
      {
        width: 800,
        height: 600,
        webPreferences: {
          nodeIntegration: true,
          preload: path.join(__dirname, 'preload.js'),
        },
        darkTheme: true,
        icon: 'public/wlan-signal.png',
      })
    this.mainWindow.loadFile('public/main.html');
    this.mainWindow.on('closed', () => {
      this.controller.model.reset();
      this.application.quit();
    });
  }

  initialize() {
    this.application.whenReady().then(() => {
      this.createWindow();
      this.addHandlers();
    });
    this.application.on('activate', () => {
      if (BrowserWindow.getAllWindows().length === 0) {
        this.createWindow();
      }
    });
    this.application.on('window-all-closed', () => {
      if (process.platform !== 'darwin') {
        this.application.quit();
      }
    });
  }
}

const model: Model = new Model();
const controller: Controller = new Controller(model);
const main: Main = new Main(app, controller);
main.initialize();

控制器.ts:

/*
* Module implementing the controller.
*/

import Utils from '../utils';
import Model from '../model/model';

class Controller {
  model: Model;

  constructor(model: Model) {
    this.model = model;
  }

  public getNetworkInterfaceControllers() {
    this.model.scanNetworkInterfaceControllers();
    return Object.keys(this.model.networkInterfaceControllers);
  }

  public getAccessPoints() {
    this.model.stopScanningAccessPoints();
    return Object.keys(this.model.accessPoints);
  }

  public setInterfaceSelection(_event: Event, iface: string) {
    this.model.usedNetworkInterfaceController = this.model.networkInterfaceControllers[iface];
  }

  public setInterfaceMac(_event: Event, randomized: boolean) {
    this.model.macRandomized = randomized;
    if (this.model.macRandomized) {
      if (this.model.usedNetworkInterfaceController.changedMac) {
        return;
      }
      const randomMac = Utils.getRandomMac();
      this.model.usedNetworkInterfaceController.changeMac(randomMac);
    } else {
      this.model.usedNetworkInterfaceController.resetMac();
    }
  }

  public setBandSelection(_event: Event, bandValues: string []) {
    this.model.bandFlags = bandValues;
  }
}

export default Controller;

型号ts:

/*
* Implementation of data model.
*/

import os from 'os';
import { ChildProcess, spawn } from 'child_process';
import NetworkInterfaceController from './networkInterfaceController';
import Utils from '../utils';
import AccessPoint from './accessPoint';

const CAPTURED_WAPS = './capturedwaps/capturedWAPS';
const CSV_PREFIX = '-01.csv';

class Model {
  networkInterfaceControllers: NetworkInterfaceController[];
  accessPoints: AccessPoint[];
  usedNetworkInterfaceController!: NetworkInterfaceController;
  macRandomized: boolean;
  bandFlags: string[];
  scanProcess!: ChildProcess;

  constructor() {
    this.networkInterfaceControllers = [];
    this.accessPoints = [];
    this.usedNetworkInterfaceController;
    this.macRandomized = false;
    this.bandFlags = [];
    this.scanProcess;
  }

  public scanNetworkInterfaceControllers() {
    const interfaces: NodeJS.Dict<os.NetworkInterfaceInfo[]> = os.networkInterfaces();
    this.networkInterfaceControllers = [];
    for (const [address, iface] of Object.entries(interfaces)) {
      if (!iface) {
        return;
      }
      if (address === 'lo' || address === 'eth0') {
        continue;
      }
      for (let i = 0; i < iface.length; i += 1) {
        if (iface[i].family === 'IPv4' && iface[i].internal === false) {
          const nic = new NetworkInterfaceController(iface[i], address);
          this.networkInterfaceControllers[address] = nic;
        }
      }
    }
  }

  public async scanAccessPoints() {
    this.scanProcess = spawn('sudo', ['airodump-ng', '--band', this.bandFlags.join(''), '-w',
      CAPTURED_WAPS, '--write-interval', '1', '--output-format', 'csv', this.usedNetworkInterfaceController.name]);
  }

  public async stopScanningAccessPoints() {
    this.scanProcess.kill('SIGINT');
    Utils.deleteClientsFromCsv(CAPTURED_WAPS + CSV_PREFIX);
    this.accessPoints = await Utils.readAccessPointsFromCsv(CAPTURED_WAPS + CSV_PREFIX);
  }

  public reset() {
    for (let i = 0; i < this.networkInterfaceControllers.length; i += 1) {
      this.networkInterfaceControllers[i].resetMac();
    }
  }
}

export default Model;

预加载.ts:

/*
* Preload file that exposes APIs for the backend communication.
*/

import { contextBridge, ipcRenderer } from 'electron';

contextBridge.exposeInMainWorld('API', {
  getNetworkInterfaceControllers: () => ipcRenderer.invoke('getNetworkInterfaceControllers'),
  updateInterfaceSelection: (iface: string) => ipcRenderer.invoke('setInterfaceSelection', iface),
  updateInterfaceMac: (randomized: boolean) => ipcRenderer.invoke('setInterfaceMac', randomized),
  updateBandSelection: (bandValues: string[]) => ipcRenderer.invoke('setBandSelection', bandValues),
  startScanning: () => ipcRenderer.invoke('startScanning'),
  getAccessPoints: () => ipcRenderer.invoke('getAccessPoints'),
});

contextBridge.exposeInMainWorld('MSG', {
  openMessageBox: (message: string) => ipcRenderer.invoke('openMessageBox', message),
});

加载应用程序时出现错误:

Error occurred in handler for 'getNetworkInterfaceControllers': TypeError: Cannot read properties of undefined (reading 'model')
    at Controller.getNetworkInterfaceControllers (/home/dave/Schreibtisch/WiFi-Deauthenticator/build/controller/controller.js:15:14)
    at node:electron/js2c/browser_init:189:579
    at EventEmitter.<anonymous> (node:electron/js2c/browser_init:161:11327)
    at EventEmitter.emit (node:events:527:28)
Error occurred in handler for 'setBandSelection': TypeError: Cannot read properties of undefined (reading 'model')
    at Controller.setBandSelection (/home/dave/Schreibtisch/WiFi-Deauthenticator/build/controller/controller.js:39:14)
    at node:electron/js2c/browser_init:189:579
    at EventEmitter.<anonymous> (node:electron/js2c/browser_init:161:11327)
    at EventEmitter.emit (node:events:527:28)

现在我知道这已经得到解决经常,但我只是不能得到我的头周围我的特殊情况。

k3bvogb1

k3bvogb11#

正如我所说,我是Javascript的新手,老实说,答案相当简单。我不得不将我的常规函数更改为箭头函数,因为常规函数有自己的这一点:
https://betterprogramming.pub/difference-between-regular-functions-and-arrow-functions-f65639aba256?gi=29d77c88a350
这样我就可以从我的函数内部访问我的模型。用适当的“this”。

相关问题