@@ -7,7 +7,8 @@ import {
|
||||
AbstractRecognizer,
|
||||
RouteRecognizer,
|
||||
RedirectRecognizer,
|
||||
RouteMatch
|
||||
RouteMatch,
|
||||
PathMatch
|
||||
} from './route_recognizer';
|
||||
import {Route, AsyncRoute, AuxRoute, Redirect, RouteDefinition} from './route_config_impl';
|
||||
import {AsyncRouteHandler} from './async_route_handler';
|
||||
@@ -117,6 +118,11 @@ export class ComponentRecognizer {
|
||||
}
|
||||
});
|
||||
|
||||
// handle cases where we are routing just to an aux route
|
||||
if (solutions.length == 0 && isPresent(urlParse) && urlParse.auxiliary.length > 0) {
|
||||
return [PromiseWrapper.resolve(new PathMatch(null, null, urlParse.auxiliary))];
|
||||
}
|
||||
|
||||
return solutions;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,9 +111,9 @@ export abstract class Instruction {
|
||||
public child: Instruction;
|
||||
public auxInstruction: {[key: string]: Instruction} = {};
|
||||
|
||||
get urlPath(): string { return this.component.urlPath; }
|
||||
get urlPath(): string { return isPresent(this.component) ? this.component.urlPath : ''; }
|
||||
|
||||
get urlParams(): string[] { return this.component.urlParams; }
|
||||
get urlParams(): string[] { return isPresent(this.component) ? this.component.urlParams : []; }
|
||||
|
||||
get specificity(): number {
|
||||
var total = 0;
|
||||
@@ -181,7 +181,7 @@ export abstract class Instruction {
|
||||
|
||||
/** @internal */
|
||||
_stringifyMatrixParams(): string {
|
||||
return this.urlParams.length > 0 ? (';' + this.component.urlParams.join(';')) : '';
|
||||
return this.urlParams.length > 0 ? (';' + this.urlParams.join(';')) : '';
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@@ -144,20 +144,18 @@ export class RouteRegistry {
|
||||
*/
|
||||
recognize(url: string, ancestorInstructions: Instruction[]): Promise<Instruction> {
|
||||
var parsedUrl = parser.parse(url);
|
||||
return this._recognize(parsedUrl, ancestorInstructions);
|
||||
return this._recognize(parsedUrl, []);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recognizes all parent-child routes, but creates unresolved auxiliary routes
|
||||
*/
|
||||
|
||||
private _recognize(parsedUrl: Url, ancestorInstructions: Instruction[],
|
||||
_aux = false): Promise<Instruction> {
|
||||
var parentComponent =
|
||||
ancestorInstructions.length > 0 ?
|
||||
ancestorInstructions[ancestorInstructions.length - 1].component.componentType :
|
||||
this._rootComponent;
|
||||
var parentInstruction = ListWrapper.last(ancestorInstructions);
|
||||
var parentComponent = isPresent(parentInstruction) ? parentInstruction.component.componentType :
|
||||
this._rootComponent;
|
||||
|
||||
var componentRecognizer = this._rules.get(parentComponent);
|
||||
if (isBlank(componentRecognizer)) {
|
||||
@@ -174,14 +172,13 @@ export class RouteRegistry {
|
||||
|
||||
if (candidate instanceof PathMatch) {
|
||||
var auxParentInstructions =
|
||||
ancestorInstructions.length > 0 ?
|
||||
[ancestorInstructions[ancestorInstructions.length - 1]] :
|
||||
[];
|
||||
ancestorInstructions.length > 0 ? [ListWrapper.last(ancestorInstructions)] : [];
|
||||
var auxInstructions =
|
||||
this._auxRoutesToUnresolved(candidate.remainingAux, auxParentInstructions);
|
||||
|
||||
var instruction = new ResolvedInstruction(candidate.instruction, null, auxInstructions);
|
||||
|
||||
if (candidate.instruction.terminal) {
|
||||
if (isBlank(candidate.instruction) || candidate.instruction.terminal) {
|
||||
return instruction;
|
||||
}
|
||||
|
||||
@@ -203,7 +200,8 @@ export class RouteRegistry {
|
||||
}
|
||||
|
||||
if (candidate instanceof RedirectMatch) {
|
||||
var instruction = this.generate(candidate.redirectTo, ancestorInstructions);
|
||||
var instruction =
|
||||
this.generate(candidate.redirectTo, ancestorInstructions.concat([null]));
|
||||
return new RedirectInstruction(instruction.component, instruction.child,
|
||||
instruction.auxInstruction);
|
||||
}
|
||||
@@ -237,69 +235,88 @@ export class RouteRegistry {
|
||||
* route boundary.
|
||||
*/
|
||||
generate(linkParams: any[], ancestorInstructions: Instruction[], _aux = false): Instruction {
|
||||
let normalizedLinkParams = splitAndFlattenLinkParams(linkParams);
|
||||
|
||||
var first = ListWrapper.first(normalizedLinkParams);
|
||||
var rest = ListWrapper.slice(normalizedLinkParams, 1);
|
||||
var params = splitAndFlattenLinkParams(linkParams);
|
||||
var prevInstruction;
|
||||
|
||||
// The first segment should be either '.' (generate from parent) or '' (generate from root).
|
||||
// When we normalize above, we strip all the slashes, './' becomes '.' and '/' becomes ''.
|
||||
if (first == '') {
|
||||
if (ListWrapper.first(params) == '') {
|
||||
params.shift();
|
||||
prevInstruction = ListWrapper.first(ancestorInstructions);
|
||||
ancestorInstructions = [];
|
||||
} else if (first == '..') {
|
||||
// we already captured the first instance of "..", so we need to pop off an ancestor
|
||||
ancestorInstructions.pop();
|
||||
while (ListWrapper.first(rest) == '..') {
|
||||
rest = ListWrapper.slice(rest, 1);
|
||||
ancestorInstructions.pop();
|
||||
if (ancestorInstructions.length <= 0) {
|
||||
throw new BaseException(
|
||||
`Link "${ListWrapper.toJSON(linkParams)}" has too many "../" segments.`);
|
||||
} else {
|
||||
prevInstruction = ancestorInstructions.length > 0 ? ancestorInstructions.pop() : null;
|
||||
|
||||
if (ListWrapper.first(params) == '.') {
|
||||
params.shift();
|
||||
} else if (ListWrapper.first(params) == '..') {
|
||||
while (ListWrapper.first(params) == '..') {
|
||||
if (ancestorInstructions.length <= 0) {
|
||||
throw new BaseException(
|
||||
`Link "${ListWrapper.toJSON(linkParams)}" has too many "../" segments.`);
|
||||
}
|
||||
prevInstruction = ancestorInstructions.pop();
|
||||
params = ListWrapper.slice(params, 1);
|
||||
}
|
||||
|
||||
// we're on to implicit child/sibling route
|
||||
} else {
|
||||
// we must only peak at the link param, and not consume it
|
||||
let routeName = ListWrapper.first(params);
|
||||
let parentComponentType = this._rootComponent;
|
||||
let grandparentComponentType = null;
|
||||
|
||||
if (ancestorInstructions.length > 1) {
|
||||
let parentComponentInstruction = ancestorInstructions[ancestorInstructions.length - 1];
|
||||
let grandComponentInstruction = ancestorInstructions[ancestorInstructions.length - 2];
|
||||
|
||||
parentComponentType = parentComponentInstruction.component.componentType;
|
||||
grandparentComponentType = grandComponentInstruction.component.componentType;
|
||||
} else if (ancestorInstructions.length == 1) {
|
||||
parentComponentType = ancestorInstructions[0].component.componentType;
|
||||
grandparentComponentType = this._rootComponent;
|
||||
}
|
||||
|
||||
// For a link with no leading `./`, `/`, or `../`, we look for a sibling and child.
|
||||
// If both exist, we throw. Otherwise, we prefer whichever exists.
|
||||
var childRouteExists = this.hasRoute(routeName, parentComponentType);
|
||||
var parentRouteExists = isPresent(grandparentComponentType) &&
|
||||
this.hasRoute(routeName, grandparentComponentType);
|
||||
|
||||
if (parentRouteExists && childRouteExists) {
|
||||
let msg =
|
||||
`Link "${ListWrapper.toJSON(linkParams)}" is ambiguous, use "./" or "../" to disambiguate.`;
|
||||
throw new BaseException(msg);
|
||||
}
|
||||
|
||||
if (parentRouteExists) {
|
||||
prevInstruction = ancestorInstructions.pop();
|
||||
}
|
||||
}
|
||||
} else if (first != '.') {
|
||||
let parentComponent = this._rootComponent;
|
||||
let grandparentComponent = null;
|
||||
if (ancestorInstructions.length > 1) {
|
||||
parentComponent =
|
||||
ancestorInstructions[ancestorInstructions.length - 1].component.componentType;
|
||||
grandparentComponent =
|
||||
ancestorInstructions[ancestorInstructions.length - 2].component.componentType;
|
||||
} else if (ancestorInstructions.length == 1) {
|
||||
parentComponent = ancestorInstructions[0].component.componentType;
|
||||
grandparentComponent = this._rootComponent;
|
||||
}
|
||||
|
||||
// For a link with no leading `./`, `/`, or `../`, we look for a sibling and child.
|
||||
// If both exist, we throw. Otherwise, we prefer whichever exists.
|
||||
var childRouteExists = this.hasRoute(first, parentComponent);
|
||||
var parentRouteExists =
|
||||
isPresent(grandparentComponent) && this.hasRoute(first, grandparentComponent);
|
||||
|
||||
if (parentRouteExists && childRouteExists) {
|
||||
let msg =
|
||||
`Link "${ListWrapper.toJSON(linkParams)}" is ambiguous, use "./" or "../" to disambiguate.`;
|
||||
throw new BaseException(msg);
|
||||
}
|
||||
if (parentRouteExists) {
|
||||
ancestorInstructions.pop();
|
||||
}
|
||||
rest = linkParams;
|
||||
}
|
||||
|
||||
if (rest[rest.length - 1] == '') {
|
||||
rest.pop();
|
||||
if (params[params.length - 1] == '') {
|
||||
params.pop();
|
||||
}
|
||||
|
||||
if (rest.length < 1) {
|
||||
if (params.length > 0 && params[0] == '') {
|
||||
params.shift();
|
||||
}
|
||||
|
||||
if (params.length < 1) {
|
||||
let msg = `Link "${ListWrapper.toJSON(linkParams)}" must include a route name.`;
|
||||
throw new BaseException(msg);
|
||||
}
|
||||
|
||||
var generatedInstruction = this._generate(rest, ancestorInstructions, _aux);
|
||||
var generatedInstruction =
|
||||
this._generate(params, ancestorInstructions, prevInstruction, _aux, linkParams);
|
||||
|
||||
// we don't clone the first (root) element
|
||||
for (var i = ancestorInstructions.length - 1; i >= 0; i--) {
|
||||
let ancestorInstruction = ancestorInstructions[i];
|
||||
if (isBlank(ancestorInstruction)) {
|
||||
break;
|
||||
}
|
||||
generatedInstruction = ancestorInstruction.replaceChild(generatedInstruction);
|
||||
}
|
||||
|
||||
@@ -308,95 +325,113 @@ export class RouteRegistry {
|
||||
|
||||
|
||||
/*
|
||||
* Internal helper that does not make any assertions about the beginning of the link DSL
|
||||
* Internal helper that does not make any assertions about the beginning of the link DSL.
|
||||
* `ancestorInstructions` are parents that will be cloned.
|
||||
* `prevInstruction` is the existing instruction that would be replaced, but which might have
|
||||
* aux routes that need to be cloned.
|
||||
*/
|
||||
private _generate(linkParams: any[], ancestorInstructions: Instruction[],
|
||||
_aux = false): Instruction {
|
||||
let parentComponent =
|
||||
ancestorInstructions.length > 0 ?
|
||||
ancestorInstructions[ancestorInstructions.length - 1].component.componentType :
|
||||
this._rootComponent;
|
||||
prevInstruction: Instruction, _aux = false, _originalLink: any[]): Instruction {
|
||||
let parentComponentType = this._rootComponent;
|
||||
let componentInstruction = null;
|
||||
let auxInstructions: {[key: string]: Instruction} = {};
|
||||
|
||||
let parentInstruction: Instruction = ListWrapper.last(ancestorInstructions);
|
||||
if (isPresent(parentInstruction) && isPresent(parentInstruction.component)) {
|
||||
parentComponentType = parentInstruction.component.componentType;
|
||||
}
|
||||
|
||||
if (linkParams.length == 0) {
|
||||
return this.generateDefault(parentComponent);
|
||||
}
|
||||
let linkIndex = 0;
|
||||
let routeName = linkParams[linkIndex];
|
||||
|
||||
if (!isString(routeName)) {
|
||||
throw new BaseException(`Unexpected segment "${routeName}" in link DSL. Expected a string.`);
|
||||
} else if (routeName == '' || routeName == '.' || routeName == '..') {
|
||||
throw new BaseException(`"${routeName}/" is only allowed at the beginning of a link DSL.`);
|
||||
}
|
||||
|
||||
let params = {};
|
||||
if (linkIndex + 1 < linkParams.length) {
|
||||
let nextSegment = linkParams[linkIndex + 1];
|
||||
if (isStringMap(nextSegment) && !isArray(nextSegment)) {
|
||||
params = nextSegment;
|
||||
linkIndex += 1;
|
||||
let defaultInstruction = this.generateDefault(parentComponentType);
|
||||
if (isBlank(defaultInstruction)) {
|
||||
throw new BaseException(
|
||||
`Link "${ListWrapper.toJSON(_originalLink)}" does not resolve to a terminal instruction.`);
|
||||
}
|
||||
return defaultInstruction;
|
||||
}
|
||||
|
||||
let auxInstructions: {[key: string]: Instruction} = {};
|
||||
var nextSegment;
|
||||
while (linkIndex + 1 < linkParams.length && isArray(nextSegment = linkParams[linkIndex + 1])) {
|
||||
let auxParentInstruction = ancestorInstructions.length > 0 ?
|
||||
[ancestorInstructions[ancestorInstructions.length - 1]] :
|
||||
[];
|
||||
let auxInstruction = this._generate(nextSegment, auxParentInstruction, true);
|
||||
// for non-aux routes, we want to reuse the predecessor's existing primary and aux routes
|
||||
// and only override routes for which the given link DSL provides
|
||||
if (isPresent(prevInstruction) && !_aux) {
|
||||
auxInstructions = StringMapWrapper.merge(prevInstruction.auxInstruction, auxInstructions);
|
||||
componentInstruction = prevInstruction.component;
|
||||
}
|
||||
|
||||
var componentRecognizer = this._rules.get(parentComponentType);
|
||||
if (isBlank(componentRecognizer)) {
|
||||
throw new BaseException(
|
||||
`Component "${getTypeNameForDebugging(parentComponentType)}" has no route config.`);
|
||||
}
|
||||
|
||||
let linkParamIndex = 0;
|
||||
let routeParams = {};
|
||||
|
||||
// first, recognize the primary route if one is provided
|
||||
if (linkParamIndex < linkParams.length && isString(linkParams[linkParamIndex])) {
|
||||
let routeName = linkParams[linkParamIndex];
|
||||
if (routeName == '' || routeName == '.' || routeName == '..') {
|
||||
throw new BaseException(`"${routeName}/" is only allowed at the beginning of a link DSL.`);
|
||||
}
|
||||
linkParamIndex += 1;
|
||||
if (linkParamIndex < linkParams.length) {
|
||||
let linkParam = linkParams[linkParamIndex];
|
||||
if (isStringMap(linkParam) && !isArray(linkParam)) {
|
||||
routeParams = linkParam;
|
||||
linkParamIndex += 1;
|
||||
}
|
||||
}
|
||||
var routeRecognizer =
|
||||
(_aux ? componentRecognizer.auxNames : componentRecognizer.names).get(routeName);
|
||||
|
||||
if (isBlank(routeRecognizer)) {
|
||||
throw new BaseException(
|
||||
`Component "${getTypeNameForDebugging(parentComponentType)}" has no route named "${routeName}".`);
|
||||
}
|
||||
|
||||
// Create an "unresolved instruction" for async routes
|
||||
// we'll figure out the rest of the route when we resolve the instruction and
|
||||
// perform a navigation
|
||||
if (isBlank(routeRecognizer.handler.componentType)) {
|
||||
var compInstruction = routeRecognizer.generateComponentPathValues(routeParams);
|
||||
return new UnresolvedInstruction(() => {
|
||||
return routeRecognizer.handler.resolveComponentType().then((_) => {
|
||||
return this._generate(linkParams, ancestorInstructions, prevInstruction, _aux,
|
||||
_originalLink);
|
||||
});
|
||||
}, compInstruction['urlPath'], compInstruction['urlParams']);
|
||||
}
|
||||
|
||||
componentInstruction = _aux ? componentRecognizer.generateAuxiliary(routeName, routeParams) :
|
||||
componentRecognizer.generate(routeName, routeParams);
|
||||
}
|
||||
|
||||
// Next, recognize auxiliary instructions.
|
||||
// If we have an ancestor instruction, we preserve whatever aux routes are active from it.
|
||||
while (linkParamIndex < linkParams.length && isArray(linkParams[linkParamIndex])) {
|
||||
let auxParentInstruction = [parentInstruction];
|
||||
let auxInstruction = this._generate(linkParams[linkParamIndex], auxParentInstruction, null,
|
||||
true, _originalLink);
|
||||
|
||||
// TODO: this will not work for aux routes with parameters or multiple segments
|
||||
auxInstructions[auxInstruction.component.urlPath] = auxInstruction;
|
||||
linkIndex += 1;
|
||||
linkParamIndex += 1;
|
||||
}
|
||||
|
||||
var componentRecognizer = this._rules.get(parentComponent);
|
||||
if (isBlank(componentRecognizer)) {
|
||||
throw new BaseException(
|
||||
`Component "${getTypeNameForDebugging(parentComponent)}" has no route config.`);
|
||||
}
|
||||
|
||||
var routeRecognizer =
|
||||
(_aux ? componentRecognizer.auxNames : componentRecognizer.names).get(routeName);
|
||||
|
||||
if (!isPresent(routeRecognizer)) {
|
||||
throw new BaseException(
|
||||
`Component "${getTypeNameForDebugging(parentComponent)}" has no route named "${routeName}".`);
|
||||
}
|
||||
|
||||
if (!isPresent(routeRecognizer.handler.componentType)) {
|
||||
var compInstruction = routeRecognizer.generateComponentPathValues(params);
|
||||
return new UnresolvedInstruction(() => {
|
||||
return routeRecognizer.handler.resolveComponentType().then(
|
||||
(_) => { return this._generate(linkParams, ancestorInstructions, _aux); });
|
||||
}, compInstruction['urlPath'], compInstruction['urlParams']);
|
||||
}
|
||||
|
||||
var componentInstruction = _aux ? componentRecognizer.generateAuxiliary(routeName, params) :
|
||||
componentRecognizer.generate(routeName, params);
|
||||
|
||||
|
||||
|
||||
var remaining = linkParams.slice(linkIndex + 1);
|
||||
|
||||
var instruction = new ResolvedInstruction(componentInstruction, null, auxInstructions);
|
||||
|
||||
// the component is sync
|
||||
if (isPresent(componentInstruction.componentType)) {
|
||||
// If the component is sync, we can generate resolved child route instructions
|
||||
// If not, we'll resolve the instructions at navigation time
|
||||
if (isPresent(componentInstruction) && isPresent(componentInstruction.componentType)) {
|
||||
let childInstruction: Instruction = null;
|
||||
if (linkIndex + 1 < linkParams.length) {
|
||||
let childAncestorComponents = ancestorInstructions.concat([instruction]);
|
||||
childInstruction = this._generate(remaining, childAncestorComponents);
|
||||
} else if (!componentInstruction.terminal) {
|
||||
// ... look for defaults
|
||||
childInstruction = this.generateDefault(componentInstruction.componentType);
|
||||
|
||||
if (isBlank(childInstruction)) {
|
||||
throw new BaseException(
|
||||
`Link "${ListWrapper.toJSON(linkParams)}" does not resolve to a terminal instruction.`);
|
||||
if (componentInstruction.terminal) {
|
||||
if (linkParamIndex >= linkParams.length) {
|
||||
// TODO: throw that there are extra link params beyond the terminal component
|
||||
}
|
||||
} else {
|
||||
let childAncestorComponents = ancestorInstructions.concat([instruction]);
|
||||
let remainingLinkParams = linkParams.slice(linkParamIndex);
|
||||
childInstruction = this._generate(remainingLinkParams, childAncestorComponents, null, false,
|
||||
_originalLink);
|
||||
}
|
||||
instruction.child = childInstruction;
|
||||
}
|
||||
@@ -422,7 +457,6 @@ export class RouteRegistry {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var defaultChild = null;
|
||||
if (isPresent(componentRecognizer.defaultRoute.handler.componentType)) {
|
||||
var componentInstruction = componentRecognizer.defaultRoute.generate({});
|
||||
|
||||
@@ -95,8 +95,6 @@ export class Router {
|
||||
throw new BaseException(`registerAuxOutlet expects to be called with an outlet with a name.`);
|
||||
}
|
||||
|
||||
// TODO...
|
||||
// what is the host of an aux route???
|
||||
var router = this.auxRouter(this.hostComponent);
|
||||
|
||||
this._auxRouters.set(outletName, router);
|
||||
@@ -224,10 +222,12 @@ export class Router {
|
||||
/** @internal */
|
||||
_settleInstruction(instruction: Instruction): Promise<any> {
|
||||
return instruction.resolveComponent().then((_) => {
|
||||
instruction.component.reuse = false;
|
||||
|
||||
var unsettledInstructions: Array<Promise<any>> = [];
|
||||
|
||||
if (isPresent(instruction.component)) {
|
||||
instruction.component.reuse = false;
|
||||
}
|
||||
|
||||
if (isPresent(instruction.child)) {
|
||||
unsettledInstructions.push(this._settleInstruction(instruction.child));
|
||||
}
|
||||
@@ -256,6 +256,9 @@ export class Router {
|
||||
if (isBlank(this._outlet)) {
|
||||
return _resolveToFalse;
|
||||
}
|
||||
if (isBlank(instruction.component)) {
|
||||
return _resolveToTrue;
|
||||
}
|
||||
return this._outlet.routerCanReuse(instruction.component)
|
||||
.then((result) => {
|
||||
instruction.component.reuse = result;
|
||||
@@ -280,7 +283,7 @@ export class Router {
|
||||
if (isPresent(instruction)) {
|
||||
childInstruction = instruction.child;
|
||||
componentInstruction = instruction.component;
|
||||
reuse = instruction.component.reuse;
|
||||
reuse = isBlank(instruction.component) || instruction.component.reuse;
|
||||
}
|
||||
if (reuse) {
|
||||
next = _resolveToTrue;
|
||||
@@ -304,8 +307,9 @@ export class Router {
|
||||
*/
|
||||
commit(instruction: Instruction, _skipLocationChange: boolean = false): Promise<any> {
|
||||
this._currentInstruction = instruction;
|
||||
|
||||
var next: Promise<any> = _resolveToTrue;
|
||||
if (isPresent(this._outlet)) {
|
||||
if (isPresent(this._outlet) && isPresent(instruction.component)) {
|
||||
var componentInstruction = instruction.component;
|
||||
if (componentInstruction.reuse) {
|
||||
next = this._outlet.reuse(componentInstruction);
|
||||
@@ -381,15 +385,12 @@ export class Router {
|
||||
}
|
||||
|
||||
private _getAncestorInstructions(): Instruction[] {
|
||||
var ancestorComponents = [];
|
||||
var ancestorInstructions = [this._currentInstruction];
|
||||
var ancestorRouter: Router = this;
|
||||
while (isPresent(ancestorRouter.parent) &&
|
||||
isPresent(ancestorRouter.parent._currentInstruction)) {
|
||||
ancestorRouter = ancestorRouter.parent;
|
||||
ancestorComponents.unshift(ancestorRouter._currentInstruction);
|
||||
while (isPresent(ancestorRouter = ancestorRouter.parent)) {
|
||||
ancestorInstructions.unshift(ancestorRouter._currentInstruction);
|
||||
}
|
||||
|
||||
return ancestorComponents;
|
||||
return ancestorInstructions;
|
||||
}
|
||||
|
||||
|
||||
@@ -505,6 +506,9 @@ class ChildRouter extends Router {
|
||||
function canActivateOne(nextInstruction: Instruction,
|
||||
prevInstruction: Instruction): Promise<boolean> {
|
||||
var next = _resolveToTrue;
|
||||
if (isBlank(nextInstruction.component)) {
|
||||
return next;
|
||||
}
|
||||
if (isPresent(nextInstruction.child)) {
|
||||
next = canActivateOne(nextInstruction.child,
|
||||
isPresent(prevInstruction) ? prevInstruction.child : null);
|
||||
|
||||
@@ -53,16 +53,24 @@ export class RouterLink {
|
||||
// the instruction passed to the router to navigate
|
||||
private _navigationInstruction: Instruction;
|
||||
|
||||
constructor(private _router: Router, private _location: Location) {}
|
||||
constructor(private _router: Router, private _location: Location) {
|
||||
// we need to update the link whenever a route changes to account for aux routes
|
||||
this._router.subscribe((_) => this._updateLink());
|
||||
}
|
||||
|
||||
// because auxiliary links take existing primary and auxiliary routes into account,
|
||||
// we need to update the link whenever params or other routes change.
|
||||
private _updateLink(): void {
|
||||
this._navigationInstruction = this._router.generate(this._routeParams);
|
||||
var navigationHref = this._navigationInstruction.toLinkUrl();
|
||||
this.visibleHref = this._location.prepareExternalUrl(navigationHref);
|
||||
}
|
||||
|
||||
get isRouteActive(): boolean { return this._router.isRouteActive(this._navigationInstruction); }
|
||||
|
||||
set routeParams(changes: any[]) {
|
||||
this._routeParams = changes;
|
||||
this._navigationInstruction = this._router.generate(this._routeParams);
|
||||
|
||||
var navigationHref = this._navigationInstruction.toLinkUrl();
|
||||
this.visibleHref = this._location.prepareExternalUrl(navigationHref);
|
||||
this._updateLink();
|
||||
}
|
||||
|
||||
onClick(): boolean {
|
||||
|
||||
Reference in New Issue
Block a user