feat(router): update recognize to handle matrix parameters
This commit is contained in:
@ -45,12 +45,13 @@ function _constructSegment(componentResolver: ComponentResolver,
|
||||
matched: _MatchResult): Promise<TreeNode<RouteSegment>[]> {
|
||||
return componentResolver.resolveComponent(matched.route.component)
|
||||
.then(factory => {
|
||||
let urlOutlet = matched.consumedUrlSegments[0].outlet;
|
||||
let segment = new RouteSegment(matched.consumedUrlSegments, matched.parameters,
|
||||
matched.consumedUrlSegments[0].outlet,
|
||||
isBlank(urlOutlet) ? DEFAULT_OUTLET_NAME : urlOutlet,
|
||||
matched.route.component, factory);
|
||||
|
||||
if (isPresent(matched.leftOverUrl)) {
|
||||
return _recognize(componentResolver, matched.route.component, matched.leftOverUrl)
|
||||
if (matched.leftOverUrl.length > 0) {
|
||||
return _recognizeMany(componentResolver, matched.route.component, matched.leftOverUrl)
|
||||
.then(children => [new TreeNode<RouteSegment>(segment, children)]);
|
||||
} else {
|
||||
return [new TreeNode<RouteSegment>(segment, [])];
|
||||
@ -78,12 +79,13 @@ function _matchWithParts(route: RouteMetadata, url: TreeNode<UrlSegment>): _Matc
|
||||
|
||||
let current = url;
|
||||
for (let i = 0; i < parts.length; ++i) {
|
||||
if (isBlank(current)) return null;
|
||||
|
||||
let p = parts[i];
|
||||
let isLastSegment = i === parts.length - 1;
|
||||
let isLastParent = i === parts.length - 2;
|
||||
let isPosParam = p.startsWith(":");
|
||||
|
||||
if (isBlank(current)) return null;
|
||||
if (!isPosParam && p != current.value.segment) return null;
|
||||
if (isLastSegment) {
|
||||
lastSegment = current;
|
||||
@ -101,10 +103,18 @@ function _matchWithParts(route: RouteMetadata, url: TreeNode<UrlSegment>): _Matc
|
||||
current = ListWrapper.first(current.children);
|
||||
}
|
||||
|
||||
let parameters = <{[key: string]: string}>StringMapWrapper.merge(lastSegment.value.parameters,
|
||||
positionalParams);
|
||||
if (isPresent(current) && isBlank(current.value.segment)) {
|
||||
lastParent = lastSegment;
|
||||
lastSegment = current;
|
||||
}
|
||||
|
||||
let p = lastSegment.value.parameters;
|
||||
let parameters =
|
||||
<{[key: string]: string}>StringMapWrapper.merge(isBlank(p) ? {} : p, positionalParams);
|
||||
let axuUrlSubtrees = isPresent(lastParent) ? lastParent.children.slice(1) : [];
|
||||
return new _MatchResult(route, consumedUrlSegments, parameters, current, axuUrlSubtrees);
|
||||
|
||||
return new _MatchResult(route, consumedUrlSegments, parameters, lastSegment.children,
|
||||
axuUrlSubtrees);
|
||||
}
|
||||
|
||||
function _checkOutletNameUniqueness(nodes: TreeNode<RouteSegment>[]): TreeNode<RouteSegment>[] {
|
||||
@ -123,8 +133,8 @@ function _checkOutletNameUniqueness(nodes: TreeNode<RouteSegment>[]): TreeNode<R
|
||||
|
||||
class _MatchResult {
|
||||
constructor(public route: RouteMetadata, public consumedUrlSegments: UrlSegment[],
|
||||
public parameters: {[key: string]: string}, public leftOverUrl: TreeNode<UrlSegment>,
|
||||
public aux: TreeNode<UrlSegment>[]) {}
|
||||
public parameters: {[key: string]: string},
|
||||
public leftOverUrl: TreeNode<UrlSegment>[], public aux: TreeNode<UrlSegment>[]) {}
|
||||
}
|
||||
|
||||
function _readMetadata(componentType: Type) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import {ComponentFactory} from 'angular2/core';
|
||||
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {Type, isBlank, isPresent} from 'angular2/src/facade/lang';
|
||||
import {DEFAULT_OUTLET_NAME} from './constants';
|
||||
import {Type, isBlank, isPresent, stringify} from 'angular2/src/facade/lang';
|
||||
|
||||
export class Tree<T> {
|
||||
/** @internal */
|
||||
@ -59,18 +58,21 @@ export class TreeNode<T> {
|
||||
}
|
||||
|
||||
export class UrlSegment {
|
||||
constructor(public segment: string, public parameters: {[key: string]: string},
|
||||
constructor(public segment: any, public parameters: {[key: string]: string},
|
||||
public outlet: string) {}
|
||||
|
||||
toString(): string {
|
||||
let outletPrefix = this.outlet == DEFAULT_OUTLET_NAME ? "" : `${this.outlet}:`;
|
||||
return `${outletPrefix}${this.segment}${_serializeParams(this.parameters)}`;
|
||||
let outletPrefix = isBlank(this.outlet) ? "" : `${this.outlet}:`;
|
||||
let segmentPrefix = isBlank(this.segment) ? "" : this.segment;
|
||||
return `${outletPrefix}${segmentPrefix}${_serializeParams(this.parameters)}`;
|
||||
}
|
||||
}
|
||||
|
||||
function _serializeParams(params: {[key: string]: string}): string {
|
||||
let res = "";
|
||||
StringMapWrapper.forEach(params, (v, k) => res += `;${k}=${v}`);
|
||||
if (isPresent(params)) {
|
||||
StringMapWrapper.forEach(params, (v, k) => res += `;${k}=${v}`);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -94,10 +96,23 @@ export class RouteSegment {
|
||||
get stringifiedUrlSegments(): string { return this.urlSegments.map(s => s.toString()).join("/"); }
|
||||
}
|
||||
|
||||
export function serializeRouteSegmentTree(tree: Tree<RouteSegment>): string {
|
||||
return _serializeRouteSegmentTree(tree._root);
|
||||
}
|
||||
|
||||
function _serializeRouteSegmentTree(node: TreeNode<RouteSegment>): string {
|
||||
let v = node.value;
|
||||
let children = node.children.map(c => _serializeRouteSegmentTree(c)).join(", ");
|
||||
return `${v.outlet}:${v.stringifiedUrlSegments}(${stringify(v.type)}) [${children}]`;
|
||||
}
|
||||
|
||||
export function equalSegments(a: RouteSegment, b: RouteSegment): boolean {
|
||||
if (isBlank(a) && !isBlank(b)) return false;
|
||||
if (!isBlank(a) && isBlank(b)) return false;
|
||||
return a._type === b._type && StringMapWrapper.equals(a.parameters, b.parameters);
|
||||
if (a._type !== b._type) return false;
|
||||
if (isBlank(a.parameters) && !isBlank(b.parameters)) return false;
|
||||
if (!isBlank(a.parameters) && isBlank(b.parameters)) return false;
|
||||
return StringMapWrapper.equals(a.parameters, b.parameters);
|
||||
}
|
||||
|
||||
export function routeSegmentComponentFactory(a: RouteSegment): ComponentFactory {
|
||||
|
Reference in New Issue
Block a user