fix(router): support relative param-only navigation (#10613)
This commit is contained in:
parent
f9da3c98d6
commit
c7f3aa71fb
|
@ -157,15 +157,30 @@ function findStartingPosition(
|
|||
return new Position(urlTree.root, true, 0);
|
||||
} else if (route.snapshot._lastPathIndex === -1) {
|
||||
return new Position(route.snapshot._urlSegment, true, 0);
|
||||
} else if (route.snapshot._lastPathIndex + 1 - normalizedChange.numberOfDoubleDots >= 0) {
|
||||
return new Position(
|
||||
route.snapshot._urlSegment, false,
|
||||
route.snapshot._lastPathIndex + 1 - normalizedChange.numberOfDoubleDots);
|
||||
} else {
|
||||
throw new Error('Invalid number of \'../\'');
|
||||
const modifier = isMatrixParams(normalizedChange.commands[0]) ? 0 : 1;
|
||||
const index = route.snapshot._lastPathIndex + modifier;
|
||||
return createPositionApplyingDoubleDots(
|
||||
route.snapshot._urlSegment, index, normalizedChange.numberOfDoubleDots);
|
||||
}
|
||||
}
|
||||
|
||||
function createPositionApplyingDoubleDots(
|
||||
group: UrlSegmentGroup, index: number, numberOfDoubleDots: number): Position {
|
||||
let g = group;
|
||||
let ci = index;
|
||||
let dd = numberOfDoubleDots;
|
||||
while (dd > ci) {
|
||||
dd -= ci;
|
||||
g = g.parent;
|
||||
if (!g) {
|
||||
throw new Error('Invalid number of \'../\'');
|
||||
}
|
||||
ci = g.segments.length;
|
||||
}
|
||||
return new Position(g, false, ci - dd);
|
||||
}
|
||||
|
||||
function getPath(command: any): any {
|
||||
return `${command}`;
|
||||
}
|
||||
|
@ -184,6 +199,7 @@ function updateSegmentGroup(
|
|||
if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
|
||||
return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
|
||||
}
|
||||
|
||||
const m = prefixedWith(segmentGroup, startIndex, commands);
|
||||
const slicedCommands = commands.slice(m.lastIndex);
|
||||
|
||||
|
@ -258,7 +274,7 @@ function createNewSegmentGroup(
|
|||
}
|
||||
|
||||
// if we start with an object literal, we need to reuse the path part from the segment
|
||||
if (i === 0 && (typeof commands[0] === 'object')) {
|
||||
if (i === 0 && isMatrixParams(commands[0])) {
|
||||
const p = segmentGroup.segments[startIndex];
|
||||
paths.push(new UrlSegment(p.path, commands[0]));
|
||||
i++;
|
||||
|
@ -267,7 +283,7 @@ function createNewSegmentGroup(
|
|||
|
||||
const curr = getPath(commands[i]);
|
||||
const next = (i < commands.length - 1) ? commands[i + 1] : null;
|
||||
if (curr && next && (typeof next === 'object')) {
|
||||
if (curr && next && isMatrixParams(next)) {
|
||||
paths.push(new UrlSegment(curr, stringify(next)));
|
||||
i += 2;
|
||||
} else {
|
||||
|
|
|
@ -139,10 +139,23 @@ describe('createUrlTree', () => {
|
|||
expect(serializer.serialize(t)).toEqual('/a/(c2//left:cp)(left:ap)');
|
||||
});
|
||||
|
||||
it('should work when given params', () => {
|
||||
it('should support parameters-only navigation', () => {
|
||||
const p = serializer.parse('/a');
|
||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, [{k: 99}]);
|
||||
expect(serializer.serialize(t)).toEqual('/a;k=99');
|
||||
});
|
||||
|
||||
it('should support parameters-only navigation (nested case)', () => {
|
||||
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, [{'x': 99}]);
|
||||
expect(serializer.serialize(t)).toEqual('/a/(c;x=99//left:cp)(left:ap)');
|
||||
expect(serializer.serialize(t)).toEqual('/a;x=99(left:ap)');
|
||||
});
|
||||
|
||||
it('should support parameters-only navigation (with a double dot)', () => {
|
||||
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||
const t =
|
||||
create(p.root.children[PRIMARY_OUTLET].children[PRIMARY_OUTLET], 0, p, ['../', {x: 5}]);
|
||||
expect(serializer.serialize(t)).toEqual('/a;x=5(left:ap)');
|
||||
});
|
||||
|
||||
it('should work when index > 0', () => {
|
||||
|
@ -157,13 +170,7 @@ describe('createUrlTree', () => {
|
|||
expect(serializer.serialize(t)).toEqual('/a/c2');
|
||||
});
|
||||
|
||||
it('should support setting matrix params', () => {
|
||||
const p = serializer.parse('/a/(c//left:cp)(left:ap)');
|
||||
const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../', {x: 5}]);
|
||||
expect(serializer.serialize(t)).toEqual('/a;x=5(left:ap)');
|
||||
});
|
||||
|
||||
xit('should support going to a parent (across segments)', () => {
|
||||
it('should support going to a parent (across segments)', () => {
|
||||
const p = serializer.parse('/q/(a/(c//left:cp)//left:qp)(left:ap)');
|
||||
|
||||
const t =
|
||||
|
|
Loading…
Reference in New Issue