[英]TypeError: Cannot read properties of undefined (reading 'model')
我是 Javascript 和 Typescript 的新手,我正在開發一個 electron 應用程序作為輔助項目。 我收到此錯誤,它可能與 function scope 有關,但我似乎不明白。 有人可以向我解釋這種行為並就如何處理這個問題給我一個建議嗎? 這是我的模塊文件:
主要.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();
Controller.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;
Model.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)
現在我知道這已經經常解決了,但我就是無法理解我的特殊情況。
正如我所說,我是 Javascript 的新手,老實說,答案相當簡單。 我不得不將我的常規函數更改為箭頭函數,因為常規函數有自己的 this:
這樣我就可以從我的函數內部訪問我的 model。 用正確的“這個”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.