|
8 | 8 |
|
9 | 9 | import {EnvironmentInjector} from '@angular/core'; |
10 | 10 | import {EmptyError, from, Observable, of, throwError} from 'rxjs'; |
11 | | -import {catchError, concatMap, first, last, map, mergeMap, scan, tap} from 'rxjs/operators'; |
| 11 | +import {catchError, concatMap, first, last, map, mergeMap, scan, switchMap, tap} from 'rxjs/operators'; |
12 | 12 |
|
13 | | -import {CanLoadFn, LoadedRouterConfig, Route, Routes} from './models'; |
| 13 | +import {LoadedRouterConfig, Route, Routes} from './models'; |
14 | 14 | import {runCanLoadGuards} from './operators/check_guards'; |
15 | | -import {prioritizedGuardValue} from './operators/prioritized_guard_value'; |
16 | 15 | import {RouterConfigLoader} from './router_config_loader'; |
17 | 16 | import {navigationCancelingError, Params, PRIMARY_OUTLET} from './shared'; |
18 | 17 | import {createRoot, squashSegmentGroup, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree} from './url_tree'; |
19 | 18 | import {forEach, wrapIntoObservable} from './utils/collection'; |
20 | 19 | import {getOrCreateRouteInjectorIfNeeded, getOutlet, sortByMatchingOutlets} from './utils/config'; |
21 | | -import {isImmediateMatch, match, noLeftoversInUrl, split} from './utils/config_matching'; |
22 | | -import {isCanLoad, isFunction, isUrlTree} from './utils/type_guards'; |
| 20 | +import {isImmediateMatch, match, matchWithChecks, noLeftoversInUrl, split} from './utils/config_matching'; |
23 | 21 |
|
24 | 22 | class NoMatch { |
25 | 23 | public segmentGroup: UrlSegmentGroup|null; |
@@ -286,41 +284,46 @@ class ApplyRedirects { |
286 | 284 | return of(new UrlSegmentGroup(segments, {})); |
287 | 285 | } |
288 | 286 |
|
289 | | - const {matched, consumedSegments, remainingSegments} = match(rawSegmentGroup, route, segments); |
290 | | - if (!matched) return noMatch(rawSegmentGroup); |
291 | | - |
292 | | - // Only create the Route's `EnvironmentInjector` if it matches the attempted navigation |
293 | | - injector = getOrCreateRouteInjectorIfNeeded(route, injector); |
294 | | - const childConfig$ = this.getChildConfig(injector, route, segments); |
295 | | - |
296 | | - return childConfig$.pipe(mergeMap((routerConfig: LoadedRouterConfig) => { |
297 | | - const childInjector = routerConfig.injector ?? injector; |
298 | | - const childConfig = routerConfig.routes; |
299 | | - |
300 | | - const {segmentGroup: splitSegmentGroup, slicedSegments} = |
301 | | - split(rawSegmentGroup, consumedSegments, remainingSegments, childConfig); |
302 | | - // See comment on the other call to `split` about why this is necessary. |
303 | | - const segmentGroup = |
304 | | - new UrlSegmentGroup(splitSegmentGroup.segments, splitSegmentGroup.children); |
305 | | - |
306 | | - if (slicedSegments.length === 0 && segmentGroup.hasChildren()) { |
307 | | - const expanded$ = this.expandChildren(childInjector, childConfig, segmentGroup); |
308 | | - return expanded$.pipe( |
309 | | - map((children: any) => new UrlSegmentGroup(consumedSegments, children))); |
310 | | - } |
311 | | - |
312 | | - if (childConfig.length === 0 && slicedSegments.length === 0) { |
313 | | - return of(new UrlSegmentGroup(consumedSegments, {})); |
314 | | - } |
315 | | - |
316 | | - const matchedOnOutlet = getOutlet(route) === outlet; |
317 | | - const expanded$ = this.expandSegment( |
318 | | - childInjector, segmentGroup, childConfig, slicedSegments, |
319 | | - matchedOnOutlet ? PRIMARY_OUTLET : outlet, true); |
320 | | - return expanded$.pipe( |
321 | | - map((cs: UrlSegmentGroup) => |
322 | | - new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children))); |
323 | | - })); |
| 287 | + return matchWithChecks(rawSegmentGroup, route, segments, injector, this.urlSerializer) |
| 288 | + .pipe( |
| 289 | + switchMap(({matched, consumedSegments, remainingSegments}) => { |
| 290 | + if (!matched) return noMatch(rawSegmentGroup); |
| 291 | + |
| 292 | + // Only create the Route's `EnvironmentInjector` if it matches the attempted |
| 293 | + // navigation |
| 294 | + injector = getOrCreateRouteInjectorIfNeeded(route, injector); |
| 295 | + const childConfig$ = this.getChildConfig(injector, route, segments); |
| 296 | + |
| 297 | + return childConfig$.pipe(mergeMap((routerConfig: LoadedRouterConfig) => { |
| 298 | + const childInjector = routerConfig.injector ?? injector; |
| 299 | + const childConfig = routerConfig.routes; |
| 300 | + |
| 301 | + const {segmentGroup: splitSegmentGroup, slicedSegments} = |
| 302 | + split(rawSegmentGroup, consumedSegments, remainingSegments, childConfig); |
| 303 | + // See comment on the other call to `split` about why this is necessary. |
| 304 | + const segmentGroup = |
| 305 | + new UrlSegmentGroup(splitSegmentGroup.segments, splitSegmentGroup.children); |
| 306 | + |
| 307 | + if (slicedSegments.length === 0 && segmentGroup.hasChildren()) { |
| 308 | + const expanded$ = this.expandChildren(childInjector, childConfig, segmentGroup); |
| 309 | + return expanded$.pipe( |
| 310 | + map((children: any) => new UrlSegmentGroup(consumedSegments, children))); |
| 311 | + } |
| 312 | + |
| 313 | + if (childConfig.length === 0 && slicedSegments.length === 0) { |
| 314 | + return of(new UrlSegmentGroup(consumedSegments, {})); |
| 315 | + } |
| 316 | + |
| 317 | + const matchedOnOutlet = getOutlet(route) === outlet; |
| 318 | + const expanded$ = this.expandSegment( |
| 319 | + childInjector, segmentGroup, childConfig, slicedSegments, |
| 320 | + matchedOnOutlet ? PRIMARY_OUTLET : outlet, true); |
| 321 | + return expanded$.pipe( |
| 322 | + map((cs: UrlSegmentGroup) => new UrlSegmentGroup( |
| 323 | + consumedSegments.concat(cs.segments), cs.children))); |
| 324 | + })); |
| 325 | + }), |
| 326 | + ); |
324 | 327 | } |
325 | 328 |
|
326 | 329 | private getChildConfig(injector: EnvironmentInjector, route: Route, segments: UrlSegment[]): |
|
0 commit comments