2013-02-15 4 views
4

사용자가 브라우저의 뒤로 버튼을 클릭하여 양식의 더티 데이터를 확인하려고하면 확인 메시지가 표시됩니다. 여기 angularjs 앱에서 리디렉션 동작 방지

이 각도 JS 컨트롤러 코드

function MyCtrl2($rootScope, $location, $scope) { 

    $rootScope.$watch(function() { 
     return $location.path(); 
    }, 

    function (newValue, oldValue) { 
     if ($scope.myForm.$dirty) { 
      var a = confirm('do you'); 
      if (!a) { 
       //how to prevent this redirect 
      } 
     } 
    }, 
    true); 
} 

MyCtrl2.$inject = ['$rootScope', '$location', '$scope']; 

그러나에 리디렉션을 방지하는 방법에

답변

2

당신이 해결하려고하는이 모든 문제의 뿌리에서 두 개의 DOM 이벤트가 있습니다 onhashchange 및 onbeforeunload. onhashchange를 검사하고 방지 할 수 있지만 브라우저의 뒤로 버튼을 사용하면 onhashchange가 트리거되지 않습니다. 더 나쁜 것은 페이지가 다시로드되지 않으면 이전에로드되지 않습니다. 즉, 페이지에서 이전 해시로 이동하기 위해 뒤로 이동하면 실행되지 않습니다. 이 때문에 뒤로를 눌러 이전 경로로 이동해도 양식은 그대로 유지됩니다.

경로 취소를 허용하는 방법에 대해서는 현재 oustanding issue on Angular's todo list입니다. 해시 문제에 대한 뒤로 버튼을 가정하면이 시점에서이 버튼을 누르고 있습니다.

마지막으로 일단 편집 된 양식에서 모든 탐색을 방지하려면 솔루션을 재 설계하여 좀 더 과감한 조치를 취할 수 있습니다. $ rootScope에서 양식이 편집하고있는 모든 데이터를 더럽지 만 불완전하다는 것을 나타내는 플래그와 함께 저장 한 다음 routeChangeStart에 이벤트 처리기를 추가하여 해당 값을 확인하고 다시 양식으로 보냅니다. 여기

가 작동 할 방법은 (그리고 plunker if you're interested) :

app.config(function($routeProvider) { 
    //set up the routes. (Important because we're going to navigate 
    // BACK to them.) 
    $routeProvider.when('/Form', { 
    controller: 'FormCtrl', 
    templateUrl: 'form.html' 
    }).otherwise({ 
    controller: 'HomeCtrl', 
    template: '<h3>Home</h3>' 
    }); 
}); 

app.run(function($rootScope, $location){ 
    //set up your rootScope formData object. 
    $rootScope.formData = {}; 

    //add a routing event to check the route 
    // and whether or not the data has been editted and then 
    // send it back to the proper form. 
    $rootScope.$on('$routeChangeStart', function() { 
    if($location.path() != '/Form' && $rootScope.formData.dirty && 
     !$rootScope.formData.complete && !confirm('Do you want to leave this form?')) { 
     $location.path('/Form'); 
    } 
    }); 

    //handle outright navigating away from the page. 
    $(window).on('beforeunload', function() { 
    if($rootScope.formData.dirty && 
     !$rootScope.formData.complete) { 
     return 'Are you sure you want to navigate away from this form?'; 
    } 
    }); 
}); 

app.controller('FormCtrl', function($scope) { 
    $scope.$watch(function(){ 
    return $scope.myForm.$dirty; 
    }, function(dirty) { 
    $scope.formData.dirty = $scope.formData.dirty | dirty; 
    }) 
}); 

다른 생각

처음

나는이에 도움이되는 지침을 개발했다,하지만 난 깨달았다는 않을 것 위에서 언급 한 문제로 인해 작동합니다. 그럼에도 불구하고, 후손을 위하여, 여기있다 : 참고 경로를 취소

app.directive('form', function ($window){ 
    return { 
    restrict: 'E', 
    link: function(scope, elem, attrs) { 

     //check for a prevent-if-dirty attribute on your form tag 
     if(attrs.preventIfDirty !== undefined) { 

     // first off, stop routing hash changes from 
     // changing the page. 
     scope.$on('$locationChangeStart', function(event) { 
      if(scope.testForm.$dirty) { 
      event.preventDefault(); 
      } 
     }); 

     // a little setup for our next piece 
     var formName = attrs.name; 
     function showWarning() { 
      return 'You have changed the form'; 
     } 

     // Now stop browser navigation from moving away 
     // from your dirty form. 
     scope.$watch(function(){ 
      return scope[formName].$dirty; 
     }, function(dirty) { 
      if(dirty) { 
      $(window).on('beforeunload', showWarning); 
      } else { 
      $(window).off('beforeunload', showWarning); 
      } 
     }); 
     } 
    } 
    }; 
}); 

Here's a plunker demonstrating it.

+0

하지만 여전히 사용자가 확인을 요청하는 메시지를 표시하지 않고 대신 사용자가 돌아갈 수 있도록 허용하지 않습니다. – iJade

+0

추가하기가 힘들지 않아야합니다. –

+0

자, 자. 이제 확인이 표시됩니다. –

11

각도에서 지금 가능하다.

$scope.$on('$locationChangeStart', function(event, newUrl, oldUrl) { 
    event.preventDefault(); 
}); 
+0

작동시키는 유일한 방법입니다. BTW는 angularJS> 1.3.7 버전 이후입니다 ... –