Oto mój problem, mam dwa widoki (View1 i View2) i kontroler dla każdego widoku (Ctrl1 i Ctrl2). W widoku 1 próbuję ostrzec użytkownika przed przypadkowym opuszczeniem strony bez zapisywania zmian.AngularJS window.onbeforeunload w jednym kontrolerze jest wyzwalany na innym kontrolerze
Używam window.onbeforeunload, który działa dobrze, ale mój problem polega na tym, że mimo że mam onbeforeunload tylko na jednym kontrolerze, zdarzenie wydaje się być również wyzwalane w drugim kontrolerze! Ale nie mam tam nawet tego wydarzenia. Kiedy użytkownik opuszcza stronę i są niezapisane zmiany, zostaje ostrzeżony przez onbeforeunload, jeśli użytkownik odrzuci alert i opuści stronę, jest on przenoszony z powrotem do drugiego widoku, jeśli użytkownik próbuje opuścić ten inny widok, otrzymamy również ostrzeżenie o niezapisanych zmianach! Nawet jeśli tak nie jest! Dlaczego to się dzieje?
Używam również $ locationChangeStart, która działa dobrze, ale tylko wtedy, gdy użytkownik zmienia trasę, a nie kiedy odświeża przeglądarkę, uderza "wstecz" lub próbuje ją zamknąć, dlatego jestem zmuszony używać onbeforeunload (jeśli masz lepsze podejście, daj mi znać). Każda pomoc lub lepsze podejście będą bardzo mile widziane!
//In this controller I check for window.onbeforeunload
app.controller("Ctrl1", function ($scope, ...)){
window.onbeforeunload = function (event) {
//Check if there was any change, if no changes, then simply let the user leave
if(!$scope.form.$dirty){
return;
}
var message = 'If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?';
if (typeof event == 'undefined') {
event = window.event;
}
if (event) {
event.returnValue = message;
}
return message;
}
//This works only when user changes routes, not when user refreshes the browsers, goes to previous page or try to close the browser
$scope.$on('$locationChangeStart', function(event) {
if (!$scope.form.$dirty) return;
var answer = confirm('If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?')
if (!answer) {
event.preventDefault();
}
});
}
//This other controller has no window.onbeforeunload, yet the event is triggered here too!
app.controller("Ctrl2", function ($scope, ...)){
//Other cool stuff ...
}
Próbowałem sprawdzania aktualnego ścieżkę z $ location.path(), aby tylko ostrzega użytkownika, gdy jest on w widoku chcę onbeforeunload być wyzwalany, ale to wydaje się trochę „hacky” rozwiązaniem byłoby nie uruchamiać onbeforeunload na innym kontrolerze.
Dodałem $ location.path()! = '/ View1' w pierwszym, który wydaje się działać, ale nie wydaje mi się to właściwe, poza tym mam nie tylko dwa widoki, mam kilka widoków, a to się trudne z kilku kontrolerów zaangażowanych:
app.controller("Ctrl1", function ($scope, ...)){
window.onbeforeunload = function (event) {
//Check if there was any change, if no changes, then simply let the user leave
if($location.path() != '/view1' || !$scope.form.$dirty){
return;
}
var message = 'If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?';
if (typeof event == 'undefined') {
event = window.event;
}
if (event) {
event.returnValue = message;
}
return message;
}
//This works only when user changes routes, not when user refreshes the browsers, goes to previous page or try to close the browser
$scope.$on('$locationChangeStart', function(event) {
if (!$scope.form.$dirty) return;
var answer = confirm('If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?')
if (!answer) {
event.preventDefault();
}
});
}
Dokładnie to, czego potrzebowałem! Dziękuję Ci! – Poncho