event.preventDefault() not working for routeChange

2020-02-09 08:55发布

问题:

Hope any angularjs gurus can help me with this.Here is my angularjs code

$scope.$on('$routeChangeStart', function(event, next, current) {
                if ($scope.myForm.$dirty) {
                    if(!confirm("Unsaved, do u want to continue?")) {
                        event.preventDefault();
                    }
                }
            });

It alerts in browser back button click when data is dirty, but on clicking cancel or ok it still completes the route change.Seems like event.preventDefault() is not working. Can any one point out what may be wrong

回答1:

I had lots of trouble finding this one, but instead of the "$routeChangeStart" event, you can listen to the "$locationChangeStart" event, for which you can prevent default:

$scope.$on("$locationChangeStart", function(event, next, current) {
    if (!confirm("You have unsaved changes, continue navigating to " + next + " ?")) {
        event.preventDefault();
    }
});

You could also always prevent default, store "next", and display a clean JS modal and decide asynchronously.

$locationChangeStart is currently undocumented but referenced here : https://github.com/angular/angular.js/issues/2109



回答2:

Fixed exactly after Angular 1.3.7 https://code.angularjs.org/1.3.7/docs/api/ngRoute/service/$route

$routeChangeStart Broadcasted before a route change. At this point the route services starts resolving all of the dependencies needed for the route change to occur. Typically this involves fetching the view template as well as any dependencies defined in resolve route property. Once all of the dependencies are resolved $routeChangeSuccess is fired.

The route change (and the $location change that triggered it) can be prevented by calling preventDefault method of the event. See $rootScope.Scope for more details about event object.



回答3:

According to the AngularJS docs (see at $broadcast) you simply cannot cancel an event of type broadcast ($routeChangeStart is of that type):

The event life cycle starts at the scope on which $broadcast was called. All listeners listening for name event on this scope get notified. Afterwards, the event propagates to all direct and indirect scopes of the current scope and calls all registered listeners along the way. The event cannot be canceled.



回答4:

This problem was fixed in the newest versions ( >= 1.3.8 ).

Since the arguments supplied to $routeChangeStart are more detailed (and often more useful), if possible, try to update your angular version ...



回答5:

The problem might persist if you are using a $stateProvider. In this case use:

$scope.$on('$stateChangeStart', function( event){
  .....
  event.preventDefault();
});