fix(router): Fix relative link generation from empty path components (#37446)
Partial resubmit of #26243 Fixes incorrect url tree generation for empty path components with children. Adds a test to demonstrate the failure of createUrlTree for those routes. Fixes #13011 Fixes #35687 PR Close #37446
This commit is contained in:
parent
946f1179e9
commit
8d817daf78
|
@ -148,7 +148,12 @@ function findStartingPosition(nav: Navigation, tree: UrlTree, route: ActivatedRo
|
|||
}
|
||||
|
||||
if (route.snapshot._lastPathIndex === -1) {
|
||||
return new Position(route.snapshot._urlSegment, true, 0);
|
||||
const segmentGroup = route.snapshot._urlSegment;
|
||||
// Pathless ActivatedRoute has _lastPathIndex === -1 but should not process children
|
||||
// see issue #26224, #13011, #35687
|
||||
// However, if the ActivatedRoute is the root we should process children like above.
|
||||
const processChildren = segmentGroup === tree.root;
|
||||
return new Position(segmentGroup, processChildren, 0);
|
||||
}
|
||||
|
||||
const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
|
||||
|
|
|
@ -11,7 +11,7 @@ import {BehaviorSubject} from 'rxjs';
|
|||
import {createUrlTree} from '../src/create_url_tree';
|
||||
import {ActivatedRoute, ActivatedRouteSnapshot, advanceActivatedRoute} from '../src/router_state';
|
||||
import {Params, PRIMARY_OUTLET} from '../src/shared';
|
||||
import {DefaultUrlSerializer, UrlSegmentGroup, UrlTree} from '../src/url_tree';
|
||||
import {DefaultUrlSerializer, UrlSegment, UrlSegmentGroup, UrlTree} from '../src/url_tree';
|
||||
|
||||
describe('createUrlTree', () => {
|
||||
const serializer = new DefaultUrlSerializer();
|
||||
|
@ -240,6 +240,29 @@ describe('createUrlTree', () => {
|
|||
const t = createRoot(p, [], {}, 'fragment');
|
||||
expect(t.fragment).toEqual('fragment');
|
||||
});
|
||||
|
||||
it('should support pathless route', () => {
|
||||
const p = serializer.parse('/a');
|
||||
const t = create(p.root.children[PRIMARY_OUTLET], -1, p, ['b']);
|
||||
expect(serializer.serialize(t)).toEqual('/b');
|
||||
});
|
||||
|
||||
it('should support pathless route with ../ at root', () => {
|
||||
const p = serializer.parse('/a');
|
||||
const t = create(p.root.children[PRIMARY_OUTLET], -1, p, ['../b']);
|
||||
expect(serializer.serialize(t)).toEqual('/b');
|
||||
});
|
||||
|
||||
it('should support pathless child of pathless root', () => {
|
||||
// i.e. routes = {path: '', loadChildren: () => import('child')...}
|
||||
// forChild: {path: '', component: Comp}
|
||||
const p = serializer.parse('');
|
||||
const empty = new UrlSegmentGroup([], {});
|
||||
p.root.children[PRIMARY_OUTLET] = empty;
|
||||
empty.parent = p.root;
|
||||
const t = create(empty, -1, p, ['lazy']);
|
||||
expect(serializer.serialize(t)).toEqual('/lazy');
|
||||
});
|
||||
});
|
||||
|
||||
function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) {
|
||||
|
@ -260,8 +283,8 @@ function create(
|
|||
expect(segment).toBeDefined();
|
||||
}
|
||||
const s = new (ActivatedRouteSnapshot as any)(
|
||||
[], <any>{}, <any>{}, '', <any>{}, PRIMARY_OUTLET, 'someComponent', null, <any>segment,
|
||||
startIndex, <any>null);
|
||||
segment.segments, <any>{}, <any>{}, '', <any>{}, PRIMARY_OUTLET, 'someComponent', null,
|
||||
<any>segment, startIndex, <any>null);
|
||||
const a = new (ActivatedRoute as any)(
|
||||
new BehaviorSubject(null!), new BehaviorSubject(null!), new BehaviorSubject(null!),
|
||||
new BehaviorSubject(null!), new BehaviorSubject(null!), PRIMARY_OUTLET, 'someComponent', s);
|
||||
|
|
Loading…
Reference in New Issue