fix(router): canDeactivate guards should run from bottom to top
Closes #15657.
This commit is contained in:
parent
eb6fb5f87e
commit
e20cfe1bbc
|
@ -839,11 +839,10 @@ export class PreActivation {
|
||||||
|
|
||||||
// reusing the node
|
// reusing the node
|
||||||
if (curr && future._routeConfig === curr._routeConfig) {
|
if (curr && future._routeConfig === curr._routeConfig) {
|
||||||
if (this.shouldRunGuardsAndResolvers(
|
const shouldRunGuardsAndResolvers = this.shouldRunGuardsAndResolvers(
|
||||||
curr, future, future._routeConfig !.runGuardsAndResolvers)) {
|
curr, future, future._routeConfig !.runGuardsAndResolvers);
|
||||||
|
if (shouldRunGuardsAndResolvers) {
|
||||||
this.canActivateChecks.push(new CanActivate(futurePath));
|
this.canActivateChecks.push(new CanActivate(futurePath));
|
||||||
const outlet = context !.outlet !;
|
|
||||||
this.canDeactivateChecks.push(new CanDeactivate(outlet.component, curr));
|
|
||||||
} else {
|
} else {
|
||||||
// we need to set the data
|
// we need to set the data
|
||||||
future.data = curr.data;
|
future.data = curr.data;
|
||||||
|
@ -859,6 +858,11 @@ export class PreActivation {
|
||||||
} else {
|
} else {
|
||||||
this.traverseChildRoutes(futureNode, currNode, parentContexts, futurePath);
|
this.traverseChildRoutes(futureNode, currNode, parentContexts, futurePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shouldRunGuardsAndResolvers) {
|
||||||
|
const outlet = context !.outlet !;
|
||||||
|
this.canDeactivateChecks.push(new CanDeactivate(outlet.component, curr));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (curr) {
|
if (curr) {
|
||||||
this.deactivateRouteAndItsChildren(currNode, context);
|
this.deactivateRouteAndItsChildren(currNode, context);
|
||||||
|
|
|
@ -2435,6 +2435,11 @@ describe('Integration', () => {
|
||||||
provide: 'canDeactivate_team',
|
provide: 'canDeactivate_team',
|
||||||
useFactory: (logger: Logger) => () => (logger.add('canDeactivate_team'), true),
|
useFactory: (logger: Logger) => () => (logger.add('canDeactivate_team'), true),
|
||||||
deps: [Logger]
|
deps: [Logger]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: 'canDeactivate_simple',
|
||||||
|
useFactory: (logger: Logger) => () => (logger.add('canDeactivate_simple'), true),
|
||||||
|
deps: [Logger]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -2468,6 +2473,31 @@ describe('Integration', () => {
|
||||||
'canDeactivate_team', 'canActivateChild_parent', 'canActivate_team'
|
'canDeactivate_team', 'canActivateChild_parent', 'canActivate_team'
|
||||||
]);
|
]);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
it('should call deactivate guards from bottom to top',
|
||||||
|
fakeAsync(inject(
|
||||||
|
[Router, Location, Logger], (router: Router, location: Location, logger: Logger) => {
|
||||||
|
const fixture = createRoot(router, RootCmp);
|
||||||
|
|
||||||
|
router.resetConfig([{
|
||||||
|
path: '',
|
||||||
|
children: [{
|
||||||
|
path: 'team/:id',
|
||||||
|
canDeactivate: ['canDeactivate_team'],
|
||||||
|
children:
|
||||||
|
[{path: '', component: SimpleCmp, canDeactivate: ['canDeactivate_simple']}],
|
||||||
|
component: TeamCmp
|
||||||
|
}]
|
||||||
|
}]);
|
||||||
|
|
||||||
|
router.navigateByUrl('/team/22');
|
||||||
|
advance(fixture);
|
||||||
|
|
||||||
|
router.navigateByUrl('/team/33');
|
||||||
|
advance(fixture);
|
||||||
|
|
||||||
|
expect(logger.logs).toEqual(['canDeactivate_simple', 'canDeactivate_team']);
|
||||||
|
})));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue