fix(router): canDeactivate guards should run from bottom to top

Closes #15657.
This commit is contained in:
Roy Ling 2017-04-01 09:13:15 +08:00 committed by Alex Rickabaugh
parent eb6fb5f87e
commit e20cfe1bbc
2 changed files with 38 additions and 4 deletions

View File

@ -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);

View File

@ -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']);
})));
}); });
}); });