Skip to content

Commit d8de648

Browse files
sliekensvicb
authored andcommitted
fix(router): cache route handle if found (#22475)
When asking the route reuse strategy to retrieve a detached route handle, store the return value in a local variable for further processing instead of asking again later. resolves #22474 PR Close #22475
1 parent 151fb66 commit d8de648

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

packages/router/src/create_router_state.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,19 @@ function createNode(
3030
return new TreeNode<ActivatedRoute>(value, children);
3131

3232
// retrieve an activated route that is used to be displayed, but is not currently displayed
33-
} else if (routeReuseStrategy.retrieve(curr.value)) {
34-
const tree: TreeNode<ActivatedRoute> =
35-
(<DetachedRouteHandleInternal>routeReuseStrategy.retrieve(curr.value)).route;
36-
setFutureSnapshotsOfActivatedRoutes(curr, tree);
37-
return tree;
38-
3933
} else {
40-
const value = createActivatedRoute(curr.value);
41-
const children = curr.children.map(c => createNode(routeReuseStrategy, c));
42-
return new TreeNode<ActivatedRoute>(value, children);
34+
const detachedRouteHandle =
35+
<DetachedRouteHandleInternal>routeReuseStrategy.retrieve(curr.value);
36+
if (detachedRouteHandle) {
37+
const tree: TreeNode<ActivatedRoute> = detachedRouteHandle.route;
38+
setFutureSnapshotsOfActivatedRoutes(curr, tree);
39+
return tree;
40+
41+
} else {
42+
const value = createActivatedRoute(curr.value);
43+
const children = curr.children.map(c => createNode(routeReuseStrategy, c));
44+
return new TreeNode<ActivatedRoute>(value, children);
45+
}
4346
}
4447
}
4548

packages/router/test/create_router_state.spec.ts

+21
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,27 @@ describe('create router state', () => {
8888
checkActivatedRoute(currC[0], ComponentA);
8989
checkActivatedRoute(currC[1], ComponentB, 'right');
9090
});
91+
92+
it('should cache the retrieved routeReuseStrategy', () => {
93+
const config = [
94+
{path: 'a', component: ComponentA}, {path: 'b', component: ComponentB, outlet: 'left'},
95+
{path: 'c', component: ComponentC, outlet: 'left'}
96+
];
97+
spyOn(reuseStrategy, 'retrieve').and.callThrough();
98+
99+
const prevState =
100+
createRouterState(reuseStrategy, createState(config, 'a(left:b)'), emptyState());
101+
advanceState(prevState);
102+
103+
// Expect 2 calls as the baseline setup
104+
expect(reuseStrategy.retrieve).toHaveBeenCalledTimes(2);
105+
106+
// This call should produce a reused activated route
107+
const state = createRouterState(reuseStrategy, createState(config, 'a(left:c)'), prevState);
108+
109+
// Verify the retrieve method has been called one more time
110+
expect(reuseStrategy.retrieve).toHaveBeenCalledTimes(3);
111+
});
91112
});
92113

93114
function advanceState(state: RouterState): void {

0 commit comments

Comments
 (0)