Skip to content

Commit

Permalink
fix(router): support outlets in non-absolute positions
Browse files Browse the repository at this point in the history
  • Loading branch information
vsavkin authored and alxhub committed Aug 8, 2016
1 parent d2d36c6 commit afcb3c0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
21 changes: 21 additions & 0 deletions modules/@angular/router/src/create_url_tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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];
Expand All @@ -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}`);
Expand Down
13 changes: 12 additions & 1 deletion modules/@angular/router/test/create_url_tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'}}]);
Expand Down Expand Up @@ -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', () => {
Expand All @@ -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,
Expand Down

0 comments on commit afcb3c0

Please sign in to comment.