Angular has CanDeactivate
guard, but you have to declare it to each path in the routes configuration.
Valid until angular/angular#11836 will be done.
You can use CanActivateChild
guard to prevent leaving from any component with single declaration.
import { Location } from '@angular/common';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivateChild, NavigationStart, Router, RouterStateSnapshot } from '@angular/router';
@Injectable({
providedIn: 'root',
})
export class LeaveGuardService implements CanActivateChild {
canLeave = true;
lastTrigger: 'imperative' | 'popstate' | 'hashchange';
constructor(
private router: Router,
private location: Location,
) {
this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
this.lastTrigger = event.navigationTrigger;
}
});
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
// Fix browser history if leaving prevented and called by back/forward navigation
if (!this.canLeave && this.lastTrigger === 'popstate') {
this.location.go(state.url);
}
return this.canLeave;
}
}
Wrap all your paths into dummy:
const routes: Routes = [
{
path: '',
canActivateChild: [LeaveGuardService],
children: [
...
],
},
];