I've got a form where I want to prevent the user from navigating away without saving their data back to the server. I borrowed code from here that lets me add a listener to the $locationChangeStartevent. I put the following code in the controller for my form, and lo and behold, nothing happened.
var cancelRouteListener = $rootScope.$on('$locationChangeStart', checkForUnsavedData);
function checkForUnsavedData (event, newURL) {
if (!$scope.form.$dirty) {
return;
}
var proceed = $window.confirm('The page has unsaved changes. Do you want to continue?');
if (proceed) {
cancelRouteListener();
$location.path(newURL);
}
event.preventDefault();
return;
}
I could see the code reaching the call to $location.path(), but the page navigation didn't change. I then, out of desperation, tried wrapping that line of the code in a call to $rootScope.$apply():
$rootScope.$apply(function () {
$location.path(newURL);
}
Lo and behold, that worked. I've got a few questions:
- Why did I need to use the
.$apply()function? I'd have thought the code would run in the context of $rootScope. - Do I really need to attach this to
$rootScope? I only need this listener when the form's route is active.