feat(router): update routerLink DSL to handle aux routes
This commit is contained in:
parent
27436270fd
commit
ded518d47f
|
@ -87,6 +87,20 @@ function normalizeCommands(commands: any[]): NormalizedNavigationCommands {
|
|||
for (let i = 0; i < commands.length; ++i) {
|
||||
const c = commands[i];
|
||||
|
||||
if (typeof c === 'object' && c.outlets !== undefined) {
|
||||
const r: {[k: string]: any} = {};
|
||||
forEach(c.outlets, (commands: any, name: string) => {
|
||||
const n = name === '' ? PRIMARY_OUTLET : name;
|
||||
if (typeof commands === 'string') {
|
||||
r[n] = commands.split('/');
|
||||
} else {
|
||||
r[n] = commands;
|
||||
}
|
||||
});
|
||||
res.push({outlets: r});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(typeof c === 'string')) {
|
||||
res.push(c);
|
||||
continue;
|
||||
|
@ -140,15 +154,13 @@ function findStartingPosition(
|
|||
}
|
||||
|
||||
function getPath(command: any): any {
|
||||
if (!(typeof command === 'string')) return command.toString();
|
||||
const parts = command.toString().split(':');
|
||||
return parts.length > 1 ? parts[1] : command;
|
||||
return `${command}`;
|
||||
}
|
||||
|
||||
function getOutlet(commands: any[]): string {
|
||||
if (!(typeof commands[0] === 'string')) return PRIMARY_OUTLET;
|
||||
const parts = commands[0].toString().split(':');
|
||||
return parts.length > 1 ? parts[0] : PRIMARY_OUTLET;
|
||||
function getOutlets(commands: any[]): {[k: string]: any[]} {
|
||||
if (!(typeof commands[0] === 'object')) return {[PRIMARY_OUTLET]: commands};
|
||||
if (commands[0].outlets === undefined) return {[PRIMARY_OUTLET]: commands};
|
||||
return commands[0].outlets;
|
||||
}
|
||||
|
||||
function updateSegment(segment: UrlSegment, startIndex: number, commands: any[]): UrlSegment {
|
||||
|
@ -177,11 +189,17 @@ function updateSegmentChildren(
|
|||
if (commands.length === 0) {
|
||||
return new UrlSegment(segment.pathsWithParams, {});
|
||||
} else {
|
||||
const outlet = getOutlet(commands);
|
||||
const outlets = getOutlets(commands);
|
||||
const children: {[key: string]: UrlSegment} = {};
|
||||
|
||||
forEach(outlets, (commands: any, outlet: string) => {
|
||||
if (commands !== null) {
|
||||
children[outlet] = updateSegment(segment.children[outlet], startIndex, commands);
|
||||
}
|
||||
});
|
||||
|
||||
forEach(segment.children, (child: UrlSegment, childOutlet: string) => {
|
||||
if (childOutlet !== outlet) {
|
||||
if (outlets[childOutlet] === undefined) {
|
||||
children[childOutlet] = child;
|
||||
}
|
||||
});
|
||||
|
@ -201,7 +219,7 @@ function prefixedWith(segment: UrlSegment, startIndex: number, commands: any[])
|
|||
const next =
|
||||
currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
|
||||
|
||||
if (curr && next && (typeof next === 'object')) {
|
||||
if (curr && next && (typeof next === 'object') && next.outlets === undefined) {
|
||||
if (!compare(curr, next, path)) return noMatch;
|
||||
currentCommandIndex += 2;
|
||||
} else {
|
||||
|
|
|
@ -209,6 +209,9 @@ export class Router {
|
|||
* // you can collapse static fragments like this
|
||||
* router.createUrlTree(['/team/33/user', userId]);
|
||||
*
|
||||
* // create /team/33/(user/11//aux:chat)
|
||||
* router.createUrlTree(['/team', 33, {outlets: {"": 'user/11', right: 'chat'}}]);
|
||||
*
|
||||
* // assuming the current url is `/team/33/user/11` and the route points to `user/11`
|
||||
*
|
||||
* // navigate to /team/33/user/11/details
|
||||
|
|
|
@ -8,6 +8,7 @@ import {DefaultUrlSerializer, UrlPathWithParams, UrlSegment, UrlTree} from '../s
|
|||
describe('createUrlTree', () => {
|
||||
const serializer = new DefaultUrlSerializer();
|
||||
|
||||
|
||||
it('should navigate to the root', () => {
|
||||
const p = serializer.parse('/');
|
||||
const t = createRoot(p, ['/']);
|
||||
|
@ -42,16 +43,40 @@ describe('createUrlTree', () => {
|
|||
|
||||
it('should support updating secondary segments', () => {
|
||||
const p = serializer.parse('/a(right:b)');
|
||||
const t = createRoot(p, ['right:c', 11, 'd']);
|
||||
const t = createRoot(p, [{outlets: {right: ['c', 11, 'd']}}]);
|
||||
expect(serializer.serialize(t)).toEqual('/a(right:c/11/d)');
|
||||
});
|
||||
|
||||
it('should support updating secondary segments (nested case)', () => {
|
||||
const p = serializer.parse('/a/(b//right:c)');
|
||||
const t = createRoot(p, ['a', 'right:d', 11, 'e']);
|
||||
const t = createRoot(p, ['a', {outlets: {right: ['d', 11, 'e']}}]);
|
||||
expect(serializer.serialize(t)).toEqual('/a/(b//right:d/11/e)');
|
||||
});
|
||||
|
||||
it('should support updating using a string', () => {
|
||||
const p = serializer.parse('/a(right:b)');
|
||||
const t = createRoot(p, [{outlets: {right: 'c/11/d'}}]);
|
||||
expect(serializer.serialize(t)).toEqual('/a(right:c/11/d)');
|
||||
});
|
||||
|
||||
it('should support updating primary and secondary segments at once', () => {
|
||||
const p = serializer.parse('/a(right:b)');
|
||||
const t = createRoot(p, [{outlets: {'': 'y/z', right: 'c/11/d'}}]);
|
||||
expect(serializer.serialize(t)).toEqual('/y/z(right:c/11/d)');
|
||||
});
|
||||
|
||||
it('should support removing primary segment', () => {
|
||||
const p = serializer.parse('/a/(b//right:c)');
|
||||
const t = createRoot(p, ['a', {outlets: {'': null, right: 'd'}}]);
|
||||
expect(serializer.serialize(t)).toEqual('/a/(right:d)');
|
||||
});
|
||||
|
||||
it('should support removing secondary segments', () => {
|
||||
const p = serializer.parse('/a(right:b)');
|
||||
const t = createRoot(p, [{outlets: {right: null}}]);
|
||||
expect(serializer.serialize(t)).toEqual('/a');
|
||||
});
|
||||
|
||||
it('should update matrix parameters', () => {
|
||||
const p = serializer.parse('/a;pp=11');
|
||||
const t = createRoot(p, ['/a', {pp: 22, dd: 33}]);
|
||||
|
|
Loading…
Reference in New Issue