Запрос на сохранение/закрытие перед закрытием окна
- Я делаю письменное выражение. Пользователи могут открыть приложение, написать текст, сохранить свою работу и т.д.
- Я пытаюсь сделать так, чтобы при нажатии кнопки
window close
пользователю предлагалось (а) сохранить свою работу (при необходимости) или (б) просто выйти. - Я пытаюсь использовать
window.beforeunload
для достижения этой цели, но обнаруживаю, что застреваю в цикле, где при попытке "выйти" появляется одно и то же приглашение до бесконечности.
Вот некоторый код:
windowCloseCheck() {
window.onbeforeunload = function(e) {
e.returnValue = false;
// window.alert('try to close me');
if(file.isUnsaved() || file.hasChanged()) {
// prompt - save or just quit?
file.fileWarning('You have unsaveeed work.', 'Save', 'Quit', function(){
// OPTION A - save
file.save();
}, function() {
// OPTION B: Quit.
ipcRenderer.send('quitter')
})
}
else {
// file is saved and no new work has been done:
ipcRenderer.send('quitter')
}
windowCloseCheck
вызывается при настройке приложения, инициируя прослушиватель событий для закрытия окна. Мое условие проверяет, является ли файл несохраненным или изменился с оригинала.
fileWarning
- это функция, которая просто оборачивает электронное диалоговое окно, в результате чего появляется всплывающее окно с двумя вариантами и соответствующими функциями для вызова для каждого варианта.
Остальная часть кода доступна, если я (возможно) опускаю необходимую информацию. Был бы рад уточнить, если я не очень ясно.
![]()
Ответы
Ответ 1
Пожалуйста, добавьте следующий блок внутри функции, где вы определили окно браузера (в моем случае функция createWindow() объявлена в main.js)
// Create the browser window.
mainWindow = new BrowserWindow({width: 400, height: 400})
mainWindow.on('close', function(e){
var choice = require('electron').dialog.showMessageBox(this,
{
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you sure you want to quit?'
});
if(choice == 1){
e.preventDefault();
}
});
Ответ 2
Вы можете добавить локальную переменную, чтобы избежать mainWindow.destroy(), например:
let showExitPrompt = true;
// ask renderer process whether should close the app (mainWindow)
mainWindow.on('close', e => {
if (showExitPrompt) {
e.preventDefault(); // Prevents the window from closing
mainWindow.webContents.send('on-app-closing');
}
});
// renderer allows the app to close
ipcMain.on('quitter', (e) => {
showExitPrompt = false;
mainWindow.close();
})
Ответ 3
В итоге я использовал window.destroy()
, чтобы разбить процесс визуализации на биты (из основного процесса):
ipcMain.on('quitter', (e) => {
mainWindow.destroy(); // necessary to bypass the repeat-quit-check in the render process.
app.quit()
})
Не уверен, что это рекомендуется, поскольку, похоже, есть лучшие способы правильно выйти из электронного приложения. Все еще рады получить любую обратную связь, если вы знаете лучший ответ!
/пожав плечами!
Ответ 4
Решение Awijeet просто отлично! Bth, спасибо Awijeet: он спас мне часы!; -)
Кроме того, если вам нужно идти дальше, знайте, что e.preventDefault()
распространяется повсюду в коде. После правильного управления preventDefault()
вам нужно повернуть переменную e.defaultPrevented = false
, чтобы вернуться к естественному поведению вашего приложения.
На самом деле, кажется, что функция e.preventDefault()
отключает переменную e.defaultPrevented
до true
, пока вы не измените ее значение.
Ответ 5
Если пользователь выберет кнопку сохранения, мы должны сохранить данные и закрыть окно, используя window.close()
.
Но, с этим подходом мы получим бесконечный цикл, который запрашивает сохранение несохраненной работы, потому что window.close()
будет снова генерировать событие окна close
.
Чтобы решить эту проблему, мы должны объявить новый логический тип var forceQuit
, для которого изначально установлено значение false
, затем мы установили его на true
после сохранения данных или если пользователь решил просто закрыть, не сохраняя данные.
import { app, BrowserWindow, dialog } from 'electron';
let win = null;
let forceQuit = false;
app.on('ready', () => {
win = new BrowserWindow({
// Your window options..
});
mainWindow.on('close', e => {
if (!forceQuit) {
const clickedButtonId = dialog.showMessageBox(mainWindow, {
type: 'warning',
buttons: ['Save', 'Cancel', 'Don't save'],
cancelId: 1,
title: 'Confirm',
message: 'You have unsaved work!'
});
if (clickedButtonId === 0) {
e.preventDefault();
console.log('Saving...');
/** Here do your data saving logic */
forceQuit = true;
win.close();
} else if (clickedButtonId === 1) {
e.preventDefault();
} else if (clickedButtonId === 2) {
forceQuit = true;
win.close();
}
}
});
});