fix(router): support outlets in non-absolute positions

This commit is contained in:
vsavkin 2016-08-07 19:04:57 -07:00 committed by Alex Rickabaugh
parent d2d36c61f3
commit afcb3c0035
2 changed files with 33 additions and 1 deletions

View File

@ -38,6 +38,11 @@ function validateCommands(n: NormalizedNavigationCommands): void {
if (n.isAbsolute && n.commands.length > 0 && isMatrixParams(n.commands[0])) {
throw new Error('Root segment cannot have matrix parameters');
}
const c = n.commands.filter(c => typeof c === 'object' && c.outlets !== undefined);
if (c.length > 0 && c[0] !== n.commands[n.commands.length - 1]) {
throw new Error('{outlets:{}} has to be the last command');
}
}
function isMatrixParams(command: any): boolean {
@ -244,8 +249,14 @@ function prefixedWith(segmentGroup: UrlSegmentGroup, startIndex: number, command
function createNewSegmentGroup(
segmentGroup: UrlSegmentGroup, startIndex: number, commands: any[]): UrlSegmentGroup {
const paths = segmentGroup.segments.slice(0, startIndex);
let i = 0;
while (i < commands.length) {
if (typeof commands[i] === 'object' && commands[i].outlets !== undefined) {
const children = createNewSegmentChldren(commands[i].outlets);
return new UrlSegmentGroup(paths, children);
}
// if we start with an object literal, we need to reuse the path part from the segment
if (i === 0 && (typeof commands[0] === 'object')) {
const p = segmentGroup.segments[startIndex];
@ -267,6 +278,16 @@ function createNewSegmentGroup(
return new UrlSegmentGroup(paths, {});
}
function createNewSegmentChldren(outlets: {[name: string]: any}): any {
const children: {[key: string]: UrlSegmentGroup} = {};
forEach(outlets, (commands: any, outlet: string) => {
if (commands !== null) {
children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands);
}
});
return children;
}
function stringify(params: {[key: string]: any}): {[key: string]: string} {
const res: {[key: string]: string} = {};
forEach(params, (v: any, k: string) => res[k] = `${v}`);

View File

@ -72,6 +72,12 @@ describe('createUrlTree', () => {
expect(serializer.serialize(t)).toEqual('/a/(b//right:d/11/e)');
});
it('should throw when outlets is not the last command', () => {
const p = serializer.parse('/a');
expect(() => createRoot(p, ['a', {outlets: {right: ['c']}}, 'c']))
.toThrowError('{outlets:{}} has to be the last command');
});
it('should support updating using a string', () => {
const p = serializer.parse('/a(right:b)');
const t = createRoot(p, [{outlets: {right: 'c/11/d'}}]);
@ -188,6 +194,12 @@ describe('createUrlTree', () => {
expect(() => create(p.root.children[PRIMARY_OUTLET], 0, p, ['../../']))
.toThrowError('Invalid number of \'../\'');
});
it('should support updating secondary segments', () => {
const p = serializer.parse('/a/b');
const t = create(p.root.children[PRIMARY_OUTLET], 1, p, [{outlets: {right: ['c']}}]);
expect(serializer.serialize(t)).toEqual('/a/b/(right:c)');
});
});
it('should set query params', () => {
@ -209,7 +221,6 @@ describe('createUrlTree', () => {
});
});
function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) {
const s = new ActivatedRouteSnapshot(
[], <any>{}, <any>{}, '', <any>{}, PRIMARY_OUTLET, 'someComponent', null, tree.root, -1,