feat(router): add an extra argument to CanDeactivate interface (#13560)

Adds a `nextState` argument to access the future url from `CanDeactivate`.

BEFORE:

    canDeactivate(component: T, route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean;

AFTER:

    canDeactivate(component: T, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean;

Closes #9853
This commit is contained in:
Dzmitry Shylovich
2016-12-28 01:08:06 +03:00
committed by Hans
parent 445ed43b9a
commit 69fa3bbc03
4 changed files with 75 additions and 8 deletions

View File

@ -1647,6 +1647,69 @@ describe('Integration', () => {
expect(location.path()).toEqual('/simple');
})));
describe('next state', () => {
let log: string[];
class ClassWithNextState implements CanDeactivate<TeamCmp> {
canDeactivate(
component: TeamCmp, currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot, nextState: RouterStateSnapshot): boolean {
log.push(currentState.url, nextState.url);
return true;
}
}
beforeEach(() => {
log = [];
TestBed.configureTestingModule({
providers: [
ClassWithNextState, {
provide: 'FunctionWithNextState',
useValue: (cmp: any, currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot, nextState: RouterStateSnapshot) => {
log.push(currentState.url, nextState.url);
return true;
}
}
]
});
});
it('should pass next state as the 4 argument when guard is a class',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp);
router.resetConfig(
[{path: 'team/:id', component: TeamCmp, canDeactivate: [ClassWithNextState]}]);
router.navigateByUrl('/team/22');
advance(fixture);
expect(location.path()).toEqual('/team/22');
router.navigateByUrl('/team/33');
advance(fixture);
expect(location.path()).toEqual('/team/33');
expect(log).toEqual(['/team/22', '/team/33']);
})));
it('should pass next state as the 4 argument when guard is a function',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp);
router.resetConfig([
{path: 'team/:id', component: TeamCmp, canDeactivate: ['FunctionWithNextState']}
]);
router.navigateByUrl('/team/22');
advance(fixture);
expect(location.path()).toEqual('/team/22');
router.navigateByUrl('/team/33');
advance(fixture);
expect(location.path()).toEqual('/team/33');
expect(log).toEqual(['/team/22', '/team/33']);
})));
});
describe('should work when given a class', () => {
class AlwaysTrue implements CanDeactivate<TeamCmp> {