Skip to content

Commit 000363e

Browse files
atscottdylhunn
authored andcommitted
refactor(router): combine functions for getting loaded config (angular#45613)
There are two functions which do the same thing and are meant to search for the closest loaded config in the `ActivatedRouteSnapshot` parent tree. These can be combined to reduce code duplication. One difference in the current implementation is the early exit for the implementation in `activate_routes` when `route.component` is defined. This early exit takes advantage of the fact that the component must then also have a `RouterOutlet`, which injects `ComponentFactoryResolver`, which would end up being the same one as what would be found if we continued to look up the parent tree. This is only a tiny optimization that will actually break when we add `providers` as a feature to the `Route` config. In this scenario, we _must_ find the correct injector in the parent routes and cannot rely on a parent `RouterOutlet` since there may be some route with a providers list in between. PR Close angular#45613
1 parent e250db4 commit 000363e

File tree

4 files changed

+28
-24
lines changed

4 files changed

+28
-24
lines changed

packages/core/test/bundling/router/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,9 @@
11451145
{
11461146
"name": "getChildRouteGuards"
11471147
},
1148+
{
1149+
"name": "getClosestLoadedConfig"
1150+
},
11481151
{
11491152
"name": "getClosureSafeProperty"
11501153
},

packages/router/src/operators/activate_routes.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {NavigationTransition} from '../router';
1616
import {ChildrenOutletContexts} from '../router_outlet_context';
1717
import {ActivatedRoute, ActivatedRouteSnapshot, advanceActivatedRoute, RouterState} from '../router_state';
1818
import {forEach} from '../utils/collection';
19+
import {getClosestLoadedConfig} from '../utils/config';
1920
import {nodeChildrenAsMap, TreeNode} from '../utils/tree';
2021

2122
export const activateRoutes =
@@ -192,7 +193,7 @@ export class ActivateRoutes {
192193
advanceActivatedRoute(stored.route.value);
193194
this.activateChildRoutes(futureNode, null, context.children);
194195
} else {
195-
const config = parentLoadedConfig(future.snapshot);
196+
const config = getClosestLoadedConfig(future.snapshot);
196197
const cmpFactoryResolver = config ? config.module.componentFactoryResolver : null;
197198

198199
context.attachRef = null;
@@ -213,13 +214,3 @@ export class ActivateRoutes {
213214
}
214215
}
215216
}
216-
217-
function parentLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig|null {
218-
for (let s = snapshot.parent; s; s = s.parent) {
219-
const route = s.routeConfig;
220-
if (route && route._loadedConfig) return route._loadedConfig;
221-
if (route && route.component) return null;
222-
}
223-
224-
return null;
225-
}

packages/router/src/utils/config.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
*/
88

99
import {EmptyOutletComponent} from '../components/empty_outlet';
10-
import {Route, Routes} from '../models';
10+
import {LoadedRouterConfig, Route, Routes} from '../models';
11+
import {ActivatedRouteSnapshot} from '../router_state';
1112
import {PRIMARY_OUTLET} from '../shared';
1213

1314
export function validateConfig(config: Routes, parentPath: string = ''): void {
@@ -133,3 +134,22 @@ export function sortByMatchingOutlets(routes: Routes, outletName: string): Route
133134
sortedConfig.push(...routes.filter(r => getOutlet(r) !== outletName));
134135
return sortedConfig;
135136
}
137+
138+
/**
139+
* Gets the first loaded config in the snapshot's parent tree.
140+
*
141+
* Returns `null` if there is no parent lazy loaded config.
142+
*
143+
* Generally used for retrieving the injector to use for getting tokens for guards/resolvers and
144+
* also used for getting the correct injector to use for creating components.
145+
*/
146+
export function getClosestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig|null {
147+
if (!snapshot) return null;
148+
149+
for (let s = snapshot.parent; s; s = s.parent) {
150+
const route = s.routeConfig;
151+
if (route && route._loadedConfig) return route._loadedConfig;
152+
}
153+
154+
return null;
155+
}

packages/router/src/utils/preactivation.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88

99
import {Injector} from '@angular/core';
1010

11-
import {LoadedRouterConfig, RunGuardsAndResolvers} from '../models';
11+
import {RunGuardsAndResolvers} from '../models';
1212
import {ChildrenOutletContexts, OutletContext} from '../router_outlet_context';
1313
import {ActivatedRouteSnapshot, equalParamsAndUrlSegments, RouterStateSnapshot} from '../router_state';
1414
import {equalPath} from '../url_tree';
1515
import {forEach, shallowEqual} from '../utils/collection';
16+
import {getClosestLoadedConfig} from '../utils/config';
1617
import {nodeChildrenAsMap, TreeNode} from '../utils/tree';
1718

1819
export class CanActivate {
@@ -54,17 +55,6 @@ export function getToken(
5455
return injector.get(token);
5556
}
5657

57-
function getClosestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConfig|null {
58-
if (!snapshot) return null;
59-
60-
for (let s = snapshot.parent; s; s = s.parent) {
61-
const route = s.routeConfig;
62-
if (route && route._loadedConfig) return route._loadedConfig;
63-
}
64-
65-
return null;
66-
}
67-
6858
function getChildRouteGuards(
6959
futureNode: TreeNode<ActivatedRouteSnapshot>, currNode: TreeNode<ActivatedRouteSnapshot>|null,
7060
contexts: ChildrenOutletContexts|null, futurePath: ActivatedRouteSnapshot[], checks: Checks = {

0 commit comments

Comments
 (0)