|
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