AngularJS window.onbeforeunload in einem Controller wird auf einem anderen Controller ausgelöst

Hier ist mein Problem, ich habe zwei Ansichten (View1 und View2) und einen Controller für jede Ansicht (Ctrl1 und Ctrl2). In View1 versuche ich, den Benutzer zu warnen, bevor er die Seite versehentlich verlässt, ohne die Änderungen zu speichern.

Ich verwende window.onbeforeunload, was gut funktioniert, aber mein Problem ist, dass obwohl ich nur auf einem Controller onbeforeunload habe, das Ereignis auch auf dem zweiten Controller ausgelöst zu werden scheint! Aber ich habe nicht einmal dieses Ereignis da drin. Wenn der Benutzer eine Seite verlässt und ungespeicherte Änderungen vorliegen, wird er vom onbeforeunload gewarnt, wenn der Benutzer die Warnung schließt und die Seite verlässt, wird er zur zweiten Ansicht zurückgeführt, wenn der Benutzer versucht, diese andere Ansicht jetzt zu verlassen. wir würden auch über nicht gespeicherte Änderungen gewarnt werden! Wenn das nicht mal der Fall ist! Warum passiert dies?

Ich verwende auch $ locationChangeStart, was gut funktioniert, aber nur, wenn der Benutzer die Route ändert, nicht, wenn er den Browser aktualisiert, auf "Zurück" klickt oder versucht, ihn zu schließen. Deshalb muss ich onbeforeunload ( Wenn Sie eine bessere Herangehensweise haben, lassen Sie es mich bitte wissen. Jede Hilfe oder ein besserer Ansatz wäre sehr dankbar!

//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 ...
}

Ich habe versucht, den aktuellen Pfad mit $ location.path () zu überprüfen, um den Benutzer nur zu warnen, wenn er in der Ansicht ist, dass das Onbeforeunload ausgelöst werden soll, aber dies scheint ein bisschen "hacky" zu sein. Die Lösung wäre, Onbeforeunload nicht auf dem anderen auszuführen Controller überhaupt.

Ich habe $ location.path () hinzugefügt! = '/ View1' in der ersten scheint das zu funktionieren, aber es scheint mir nicht richtig zu sein, außerdem habe ich nicht nur zwei Ansichten, ich habe mehrere Ansichten und dies würde mit mehr beteiligten Controllern schwierig werden:

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();
    }
  });
}

Antworten auf die Frage(1)

Ihre Antwort auf die Frage