mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
Revert "Revert "fix(router): Ensure canMatch guards run on wildcard routes (#53239)" (#53339)" (#53342)
This reverts commit ac8eb5b943.
PR Close #53342
This commit is contained in:
parent
dc51f6ee3b
commit
a9872ccbb9
4 changed files with 31 additions and 27 deletions
|
|
@ -1106,9 +1106,6 @@
|
|||
{
|
||||
"name": "createUrlTreeFromSegmentGroup"
|
||||
},
|
||||
{
|
||||
"name": "createWildcardMatchResult"
|
||||
},
|
||||
{
|
||||
"name": "deactivateRouteAndItsChildren"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {EnvironmentInjector, Type, ɵRuntimeError as RuntimeError} from '@angular/core';
|
||||
import {from, Observable, of} from 'rxjs';
|
||||
import {catchError, concatMap, defaultIfEmpty, first, last as rxjsLast, map, mergeMap, scan, switchMap, tap} from 'rxjs/operators';
|
||||
import {catchError, concatMap, defaultIfEmpty, first, last, map, mergeMap, scan, switchMap, tap} from 'rxjs/operators';
|
||||
|
||||
import {AbsoluteRedirect, ApplyRedirects, canLoadFails, noMatch, NoMatch} from './apply_redirects';
|
||||
import {createUrlTreeFromSnapshot} from './create_url_tree';
|
||||
|
|
@ -19,9 +19,8 @@ import {RouterConfigLoader} from './router_config_loader';
|
|||
import {ActivatedRouteSnapshot, getInherited, ParamsInheritanceStrategy, RouterStateSnapshot} from './router_state';
|
||||
import {PRIMARY_OUTLET} from './shared';
|
||||
import {UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree} from './url_tree';
|
||||
import {last} from './utils/collection';
|
||||
import {getOutlet, sortByMatchingOutlets} from './utils/config';
|
||||
import {isImmediateMatch, match, MatchResult, matchWithChecks, noLeftoversInUrl, split} from './utils/config_matching';
|
||||
import {isImmediateMatch, match, matchWithChecks, noLeftoversInUrl, split} from './utils/config_matching';
|
||||
import {TreeNode} from './utils/tree';
|
||||
import {isEmptyError} from './utils/type_guards';
|
||||
|
||||
|
|
@ -162,7 +161,7 @@ export class Recognizer {
|
|||
return children;
|
||||
}),
|
||||
defaultIfEmpty(null as TreeNode<ActivatedRouteSnapshot>[] | null),
|
||||
rxjsLast(),
|
||||
last(),
|
||||
mergeMap(children => {
|
||||
if (children === null) return noMatch(segmentGroup);
|
||||
// Because we may have matched two outlets to the same empty path segment, we can have
|
||||
|
|
@ -235,8 +234,7 @@ export class Recognizer {
|
|||
consumedSegments,
|
||||
positionalParamSegments,
|
||||
remainingSegments,
|
||||
} = route.path === '**' ? createWildcardMatchResult(segments) :
|
||||
match(segmentGroup, route, segments);
|
||||
} = match(segmentGroup, route, segments);
|
||||
if (!matched) return noMatch(segmentGroup);
|
||||
|
||||
// TODO(atscott): Move all of this under an if(ngDevMode) as a breaking change and allow stack
|
||||
|
|
@ -268,17 +266,13 @@ export class Recognizer {
|
|||
matchSegmentAgainstRoute(
|
||||
injector: EnvironmentInjector, rawSegment: UrlSegmentGroup, route: Route,
|
||||
segments: UrlSegment[], outlet: string): Observable<TreeNode<ActivatedRouteSnapshot>> {
|
||||
let matchResult: Observable<MatchResult>;
|
||||
|
||||
const matchResult = matchWithChecks(rawSegment, route, segments, injector, this.urlSerializer);
|
||||
if (route.path === '**') {
|
||||
matchResult = of(createWildcardMatchResult(segments));
|
||||
// Prior versions of the route matching algorithm would stop matching at the wildcard route.
|
||||
// We should investigate a better strategy for any existing children. Otherwise, these
|
||||
// child segments are silently dropped from the navigation.
|
||||
// https://github.com/angular/angular/issues/40089
|
||||
rawSegment.children = {};
|
||||
} else {
|
||||
matchResult = matchWithChecks(rawSegment, route, segments, injector, this.urlSerializer);
|
||||
}
|
||||
|
||||
return matchResult.pipe(switchMap((result) => {
|
||||
|
|
@ -437,13 +431,3 @@ function getData(route: Route): Data {
|
|||
function getResolve(route: Route): ResolveData {
|
||||
return route.resolve || {};
|
||||
}
|
||||
|
||||
function createWildcardMatchResult(segments: UrlSegment[]): MatchResult {
|
||||
return {
|
||||
matched: true,
|
||||
parameters: segments.length > 0 ? last(segments)!.parameters : {},
|
||||
consumedSegments: segments,
|
||||
remainingSegments: [],
|
||||
positionalParamSegments: {},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {runCanMatchGuards} from '../operators/check_guards';
|
|||
import {defaultUrlMatcher, PRIMARY_OUTLET} from '../shared';
|
||||
import {UrlSegment, UrlSegmentGroup, UrlSerializer} from '../url_tree';
|
||||
|
||||
import {last} from './collection';
|
||||
import {getOrCreateRouteInjectorIfNeeded, getOutlet} from './config';
|
||||
|
||||
export interface MatchResult {
|
||||
|
|
@ -52,6 +53,10 @@ export function matchWithChecks(
|
|||
|
||||
export function match(
|
||||
segmentGroup: UrlSegmentGroup, route: Route, segments: UrlSegment[]): MatchResult {
|
||||
if (route.path === '**') {
|
||||
return createWildcardMatchResult(segments);
|
||||
}
|
||||
|
||||
if (route.path === '') {
|
||||
if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
|
||||
return {...noMatch};
|
||||
|
|
@ -88,6 +93,16 @@ export function match(
|
|||
};
|
||||
}
|
||||
|
||||
function createWildcardMatchResult(segments: UrlSegment[]): MatchResult {
|
||||
return {
|
||||
matched: true,
|
||||
parameters: segments.length > 0 ? last(segments)!.parameters : {},
|
||||
consumedSegments: segments,
|
||||
remainingSegments: [],
|
||||
positionalParamSegments: {},
|
||||
};
|
||||
}
|
||||
|
||||
export function split(
|
||||
segmentGroup: UrlSegmentGroup, consumedSegments: UrlSegment[], slicedSegments: UrlSegment[],
|
||||
config: Route[]) {
|
||||
|
|
@ -183,9 +198,6 @@ export function isImmediateMatch(
|
|||
(outlet === PRIMARY_OUTLET || !emptyPathMatch(rawSegment, segments, route))) {
|
||||
return false;
|
||||
}
|
||||
if (route.path === '**') {
|
||||
return true;
|
||||
}
|
||||
return match(rawSegment, route, segments).matched;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -653,6 +653,17 @@ describe('recognize', async () => {
|
|||
expect(s.root.fragment).toEqual('f1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('guards', () => {
|
||||
it('should run canMatch guards on wildcard routes', async () => {
|
||||
const config = [
|
||||
{path: '**', component: ComponentA, data: {id: 'a'}, canMatch: [() => false]},
|
||||
{path: '**', component: ComponentB, data: {id: 'b'}}
|
||||
];
|
||||
const s = await recognize(config, 'a');
|
||||
expect(s.root.firstChild!.data['id']).toEqual('b');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
async function recognize(
|
||||
|
|
|
|||
Loading…
Reference in a new issue