feat(router): add ActivationStart/End events

This commit is contained in:
Jason Aden
2017-09-06 11:00:32 -07:00
committed by Matias Niemelä
parent 4a0466e574
commit 8f7915022c
8 changed files with 169 additions and 40 deletions

View File

@ -288,6 +288,38 @@ export class ChildActivationEnd {
}
}
/**
* @whatItDoes Represents the start of end of the Resolve phase of routing. See note on
* {@link ActivationEnd} for use of this experimental API.
*
* @experimental
*/
export class ActivationStart {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ChildActivationStart(path: '${path}')`;
}
}
/**
* @whatItDoes Represents the start of end of the Resolve phase of routing. See note on
* {@link ActivationStart} for use of this experimental API.
*
* @experimental
*/
export class ActivationEnd {
constructor(
/** @docsNotRequired */
public snapshot: ActivatedRouteSnapshot) {}
toString(): string {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
return `ChildActivationEnd(path: '${path}')`;
}
}
/**
* @whatItDoes Represents a router event, allowing you to track the lifecycle of the router.
*
@ -310,4 +342,5 @@ export class ChildActivationEnd {
* @stable
*/
export type Event = RouterEvent | RouteConfigLoadStart | RouteConfigLoadEnd | ChildActivationStart |
ChildActivationEnd;
ChildActivationEnd | ActivationStart | ActivationEnd;
;

View File

@ -11,7 +11,7 @@ export {Data, LoadChildren, LoadChildrenCallback, ResolveData, Route, Routes, Ru
export {RouterLink, RouterLinkWithHref} from './directives/router_link';
export {RouterLinkActive} from './directives/router_link_active';
export {RouterOutlet} from './directives/router_outlet';
export {ChildActivationEnd, ChildActivationStart, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized} from './events';
export {ActivationEnd, ActivationStart, ChildActivationEnd, ChildActivationStart, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized} from './events';
export {CanActivate, CanActivateChild, CanDeactivate, CanLoad, Resolve} from './interfaces';
export {DetachedRouteHandle, RouteReuseStrategy} from './route_reuse_strategy';
export {NavigationExtras, Router} from './router';

View File

@ -19,7 +19,7 @@ import {mergeMap} from 'rxjs/operator/mergeMap';
import {reduce} from 'rxjs/operator/reduce';
import {LoadedRouterConfig, ResolveData, RunGuardsAndResolvers} from './config';
import {ChildActivationStart, Event} from './events';
import {ActivationStart, ChildActivationStart, Event} from './events';
import {ChildrenOutletContexts, OutletContext} from './router_outlet_context';
import {ActivatedRouteSnapshot, RouterStateSnapshot, equalParamsAndUrlSegments, inheritedParamsDataResolve} from './router_state';
import {andObservables, forEach, shallowEqual, wrapIntoObservable} from './utils/collection';
@ -201,14 +201,30 @@ export class PreActivation {
private runCanActivateChecks(): Observable<boolean> {
const checks$ = from(this.canActivateChecks);
const runningChecks$ = concatMap.call(
checks$, (check: CanActivate) => andObservables(from([
this.fireChildActivationStart(check.route.parent),
this.runCanActivateChild(check.path), this.runCanActivate(check.route)
])));
checks$,
(check: CanActivate) => andObservables(from([
this.fireChildActivationStart(check.route.parent), this.fireActivationStart(check.route),
this.runCanActivateChild(check.path), this.runCanActivate(check.route)
])));
return every.call(runningChecks$, (result: boolean) => result === true);
// this.fireChildActivationStart(check.path),
}
/**
* This should fire off `ChildActivationStart` events for each route being activated at this
* level.
* In other words, if you're activating `a` and `b` below, `path` will contain the
* `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
* return
* `true` so checks continue to run.
*/
private fireActivationStart(snapshot: ActivatedRouteSnapshot|null): Observable<boolean> {
if (snapshot !== null && this.forwardEvent) {
this.forwardEvent(new ActivationStart(snapshot));
}
return of (true);
}
/**
* This should fire off `ChildActivationStart` events for each route being activated at this
* level.
@ -223,6 +239,7 @@ export class PreActivation {
}
return of (true);
}
private runCanActivate(future: ActivatedRouteSnapshot): Observable<boolean> {
const canActivate = future._routeConfig ? future._routeConfig.canActivate : null;
if (!canActivate || canActivate.length === 0) return of (true);

View File

@ -21,7 +21,7 @@ import {applyRedirects} from './apply_redirects';
import {LoadedRouterConfig, QueryParamsHandling, Route, Routes, validateConfig} from './config';
import {createRouterState} from './create_router_state';
import {createUrlTree} from './create_url_tree';
import {ChildActivationEnd, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RoutesRecognized} from './events';
import {ActivationEnd, ChildActivationEnd, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RoutesRecognized} from './events';
import {PreActivation} from './pre_activation';
import {recognize} from './recognize';
import {DefaultRouteReuseStrategy, DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy';
@ -862,8 +862,10 @@ class ActivateRoutes {
futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>|null,
contexts: ChildrenOutletContexts): void {
const children: {[outlet: string]: any} = nodeChildrenAsMap(currNode);
futureNode.children.forEach(
c => { this.activateRoutes(c, children[c.value.outlet], contexts); });
futureNode.children.forEach(c => {
this.activateRoutes(c, children[c.value.outlet], contexts);
this.forwardEvent(new ActivationEnd(c.value.snapshot));
});
if (futureNode.children.length) {
this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
}