programing

한 컨트롤러에서 언로드하기 전에 AngularJS window.on이 다른 컨트롤러에서 트리거됨

telecom 2023. 11. 6. 21:39
반응형

한 컨트롤러에서 언로드하기 전에 AngularJS window.on이 다른 컨트롤러에서 트리거됨

여기 내 문제가 있습니다. 두 개의 뷰(View1 및 View2)와 각 뷰에 대한 컨트롤러(Ctrl1 및 Ctrl2)가 있습니다.View1에서 사용자가 변경 사항을 저장하지 않고 실수로 페이지를 떠나기 전에 경고하려고 합니다.

window.on before unload를 사용하고 있는데, window.on before unload는 잘 작동하지만, 문제는 한 개의 컨트롤러에서만 on before unload를 사용하고 있는데, 두 번째 컨트롤러에서도 이벤트가 트리거되는 것 같습니다.하지만 저는 거기에 그런 행사조차 없습니다.사용자가 페이지를 떠났을 때 저장되지 않은 변경 사항이 있을 경우 다운로드 전에 경고를 받게 되며, 사용자가 경고를 무시하고 페이지를 떠난 경우 두 번째 보기로 다시 이동하게 되며, 사용자가 이 다른 보기를 지금 떠나려고 할 경우 저장되지 않은 변경 사항에 대해 경고를 받게 됩니다!그렇지도 않을 때!왜 이런 일이 생기는 건가요?

$locationChangeStart도 사용하고 있는데, 이는 정상적으로 작동하지만 사용자가 경로를 변경할 때만 사용할 수 있고 브라우저를 새로 고치거나 '뒤로'를 누르거나 닫으려고 할 때만 사용할 수 있기 때문입니다(더 나은 접근 방법이 있으면 알려주세요).어떤 도움이나 더 나은 접근법이라도 대단히 감사하겠습니다!

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

언로드 전에 켜기 전에 트리거하기를 원하는 보기에 사용자에게 경고하기 위해 $location.path()로 현재 경로를 확인하려고 했지만, 이는 다른 컨트롤러에서 언로드하기 전에 실행되지 않는 것이 해결책인 것 같습니다.

번째에 $location.path () != '/view1'을 추가했는데, 이는 작동하는 것처럼 보이지만, 보기가 두 개일 뿐만 아니라 여러 개일 뿐만 아니라, 컨트롤러가 더 포함되면 까다로워질 것입니다.

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

on before unload 이벤트를 정의한 컨트롤러가 범위를 벗어날 경우 등록 취소:

$scope.$on('$destroy', function() {
    delete window.onbeforeunload;
});

저는 위의 해결책을 시도했을 뿐인데, 그것은 저에게 효과가 없었습니다.수동으로 타이핑해도delete window.onbeforeunload콘솔에서 기능이 제거되지 않습니다.대신 속성을 정의되지 않은 상태로 설정해야 했습니다.

$scope.$on('$destroy', function(e){
  $window.onbeforeunload = undefined;
});

angular-ui-router를 사용하시는 분들은.$stateChangeStart대신에$locationChangeStart,예.

$scope.$on('$stateChangeStart', function (event){
  if (forbit){
    event.preventDefault()
  }
  else{  
    return
  }
})

이에 대한 업데이트로, angular-ui-router를 사용하는 모든 사람들에게, 저는 이제 $transition을 당신의 컨트롤러에 전달하고 사용합니다.

$transitions.onStart({}, function ($transition)
{
    $transition.abort();
    //return false;
});

언급URL : https://stackoverflow.com/questions/25533513/angularjs-window-onbeforeunload-in-one-controller-is-being-triggered-on-another

반응형