feat(router): add ActivationStart/End events
This commit is contained in:
parent
4a0466e574
commit
8f7915022c
|
@ -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.
|
* @whatItDoes Represents a router event, allowing you to track the lifecycle of the router.
|
||||||
*
|
*
|
||||||
|
@ -310,4 +342,5 @@ export class ChildActivationEnd {
|
||||||
* @stable
|
* @stable
|
||||||
*/
|
*/
|
||||||
export type Event = RouterEvent | RouteConfigLoadStart | RouteConfigLoadEnd | ChildActivationStart |
|
export type Event = RouterEvent | RouteConfigLoadStart | RouteConfigLoadEnd | ChildActivationStart |
|
||||||
ChildActivationEnd;
|
ChildActivationEnd | ActivationStart | ActivationEnd;
|
||||||
|
;
|
||||||
|
|
|
@ -11,7 +11,7 @@ export {Data, LoadChildren, LoadChildrenCallback, ResolveData, Route, Routes, Ru
|
||||||
export {RouterLink, RouterLinkWithHref} from './directives/router_link';
|
export {RouterLink, RouterLinkWithHref} from './directives/router_link';
|
||||||
export {RouterLinkActive} from './directives/router_link_active';
|
export {RouterLinkActive} from './directives/router_link_active';
|
||||||
export {RouterOutlet} from './directives/router_outlet';
|
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 {CanActivate, CanActivateChild, CanDeactivate, CanLoad, Resolve} from './interfaces';
|
||||||
export {DetachedRouteHandle, RouteReuseStrategy} from './route_reuse_strategy';
|
export {DetachedRouteHandle, RouteReuseStrategy} from './route_reuse_strategy';
|
||||||
export {NavigationExtras, Router} from './router';
|
export {NavigationExtras, Router} from './router';
|
||||||
|
|
|
@ -19,7 +19,7 @@ import {mergeMap} from 'rxjs/operator/mergeMap';
|
||||||
import {reduce} from 'rxjs/operator/reduce';
|
import {reduce} from 'rxjs/operator/reduce';
|
||||||
|
|
||||||
import {LoadedRouterConfig, ResolveData, RunGuardsAndResolvers} from './config';
|
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 {ChildrenOutletContexts, OutletContext} from './router_outlet_context';
|
||||||
import {ActivatedRouteSnapshot, RouterStateSnapshot, equalParamsAndUrlSegments, inheritedParamsDataResolve} from './router_state';
|
import {ActivatedRouteSnapshot, RouterStateSnapshot, equalParamsAndUrlSegments, inheritedParamsDataResolve} from './router_state';
|
||||||
import {andObservables, forEach, shallowEqual, wrapIntoObservable} from './utils/collection';
|
import {andObservables, forEach, shallowEqual, wrapIntoObservable} from './utils/collection';
|
||||||
|
@ -201,14 +201,30 @@ export class PreActivation {
|
||||||
private runCanActivateChecks(): Observable<boolean> {
|
private runCanActivateChecks(): Observable<boolean> {
|
||||||
const checks$ = from(this.canActivateChecks);
|
const checks$ = from(this.canActivateChecks);
|
||||||
const runningChecks$ = concatMap.call(
|
const runningChecks$ = concatMap.call(
|
||||||
checks$, (check: CanActivate) => andObservables(from([
|
checks$,
|
||||||
this.fireChildActivationStart(check.route.parent),
|
(check: CanActivate) => andObservables(from([
|
||||||
this.runCanActivateChild(check.path), this.runCanActivate(check.route)
|
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);
|
return every.call(runningChecks$, (result: boolean) => result === true);
|
||||||
// this.fireChildActivationStart(check.path),
|
// 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
|
* This should fire off `ChildActivationStart` events for each route being activated at this
|
||||||
* level.
|
* level.
|
||||||
|
@ -223,6 +239,7 @@ export class PreActivation {
|
||||||
}
|
}
|
||||||
return of (true);
|
return of (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private runCanActivate(future: ActivatedRouteSnapshot): Observable<boolean> {
|
private runCanActivate(future: ActivatedRouteSnapshot): Observable<boolean> {
|
||||||
const canActivate = future._routeConfig ? future._routeConfig.canActivate : null;
|
const canActivate = future._routeConfig ? future._routeConfig.canActivate : null;
|
||||||
if (!canActivate || canActivate.length === 0) return of (true);
|
if (!canActivate || canActivate.length === 0) return of (true);
|
||||||
|
|
|
@ -21,7 +21,7 @@ import {applyRedirects} from './apply_redirects';
|
||||||
import {LoadedRouterConfig, QueryParamsHandling, Route, Routes, validateConfig} from './config';
|
import {LoadedRouterConfig, QueryParamsHandling, Route, Routes, validateConfig} from './config';
|
||||||
import {createRouterState} from './create_router_state';
|
import {createRouterState} from './create_router_state';
|
||||||
import {createUrlTree} from './create_url_tree';
|
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 {PreActivation} from './pre_activation';
|
||||||
import {recognize} from './recognize';
|
import {recognize} from './recognize';
|
||||||
import {DefaultRouteReuseStrategy, DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy';
|
import {DefaultRouteReuseStrategy, DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy';
|
||||||
|
@ -862,8 +862,10 @@ class ActivateRoutes {
|
||||||
futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>|null,
|
futureNode: TreeNode<ActivatedRoute>, currNode: TreeNode<ActivatedRoute>|null,
|
||||||
contexts: ChildrenOutletContexts): void {
|
contexts: ChildrenOutletContexts): void {
|
||||||
const children: {[outlet: string]: any} = nodeChildrenAsMap(currNode);
|
const children: {[outlet: string]: any} = nodeChildrenAsMap(currNode);
|
||||||
futureNode.children.forEach(
|
futureNode.children.forEach(c => {
|
||||||
c => { this.activateRoutes(c, children[c.value.outlet], contexts); });
|
this.activateRoutes(c, children[c.value.outlet], contexts);
|
||||||
|
this.forwardEvent(new ActivationEnd(c.value.snapshot));
|
||||||
|
});
|
||||||
if (futureNode.children.length) {
|
if (futureNode.children.length) {
|
||||||
this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
|
this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,8 +84,8 @@ describe('bootstrap', () => {
|
||||||
expect(data['test']).toEqual('test-data');
|
expect(data['test']).toEqual('test-data');
|
||||||
expect(log).toEqual([
|
expect(log).toEqual([
|
||||||
'TestModule', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart',
|
'TestModule', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart',
|
||||||
'ChildActivationStart', 'GuardsCheckEnd', 'ResolveStart', 'ResolveEnd', 'RootCmp',
|
'ChildActivationStart', 'ActivationStart', 'GuardsCheckEnd', 'ResolveStart', 'ResolveEnd',
|
||||||
'ChildActivationEnd', 'NavigationEnd'
|
'RootCmp', 'ActivationEnd', 'ChildActivationEnd', 'NavigationEnd'
|
||||||
]);
|
]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -122,7 +122,7 @@ describe('bootstrap', () => {
|
||||||
// ResolveEnd has not been emitted yet because bootstrap returned too early
|
// ResolveEnd has not been emitted yet because bootstrap returned too early
|
||||||
expect(log).toEqual([
|
expect(log).toEqual([
|
||||||
'TestModule', 'RootCmp', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart',
|
'TestModule', 'RootCmp', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart',
|
||||||
'ChildActivationStart', 'GuardsCheckEnd', 'ResolveStart'
|
'ChildActivationStart', 'ActivationStart', 'GuardsCheckEnd', 'ResolveStart'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
router.events.subscribe((e) => {
|
router.events.subscribe((e) => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {ChangeDetectionStrategy, Component, Injectable, NgModule, NgModuleFactor
|
||||||
import {ComponentFixture, TestBed, fakeAsync, inject, tick} from '@angular/core/testing';
|
import {ComponentFixture, TestBed, fakeAsync, inject, tick} from '@angular/core/testing';
|
||||||
import {By} from '@angular/platform-browser/src/dom/debug/by';
|
import {By} from '@angular/platform-browser/src/dom/debug/by';
|
||||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, ChildActivationEnd, ChildActivationStart, DetachedRouteHandle, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, PRIMARY_OUTLET, ParamMap, Params, PreloadAllModules, PreloadingStrategy, Resolve, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterEvent, RouterModule, RouterPreloader, RouterStateSnapshot, RoutesRecognized, RunGuardsAndResolvers, UrlHandlingStrategy, UrlSegmentGroup, UrlTree} from '@angular/router';
|
import {ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart, CanActivate, CanDeactivate, ChildActivationEnd, ChildActivationStart, DetachedRouteHandle, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, PRIMARY_OUTLET, ParamMap, Params, PreloadAllModules, PreloadingStrategy, Resolve, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterEvent, RouterModule, RouterPreloader, RouterStateSnapshot, RoutesRecognized, RunGuardsAndResolvers, UrlHandlingStrategy, UrlSegmentGroup, UrlTree} from '@angular/router';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
import {Observer} from 'rxjs/Observer';
|
import {Observer} from 'rxjs/Observer';
|
||||||
import {of } from 'rxjs/observable/of';
|
import {of } from 'rxjs/observable/of';
|
||||||
|
@ -705,18 +705,31 @@ describe('Integration', () => {
|
||||||
expect(user.recordedParams).toEqual([{name: 'init'}, {name: 'fedor'}]);
|
expect(user.recordedParams).toEqual([{name: 'init'}, {name: 'fedor'}]);
|
||||||
|
|
||||||
expectEvents(recordedEvents, [
|
expectEvents(recordedEvents, [
|
||||||
[NavigationStart, '/user/init'], [RoutesRecognized, '/user/init'],
|
[NavigationStart, '/user/init'],
|
||||||
[GuardsCheckStart, '/user/init'], [ChildActivationStart],
|
[RoutesRecognized, '/user/init'],
|
||||||
[GuardsCheckEnd, '/user/init'], [ResolveStart, '/user/init'],
|
[GuardsCheckStart, '/user/init'],
|
||||||
[ResolveEnd, '/user/init'], [ChildActivationEnd],
|
[ChildActivationStart],
|
||||||
|
[ActivationStart],
|
||||||
|
[GuardsCheckEnd, '/user/init'],
|
||||||
|
[ResolveStart, '/user/init'],
|
||||||
|
[ResolveEnd, '/user/init'],
|
||||||
|
[ActivationEnd],
|
||||||
|
[ChildActivationEnd],
|
||||||
[NavigationEnd, '/user/init'],
|
[NavigationEnd, '/user/init'],
|
||||||
|
|
||||||
[NavigationStart, '/user/victor'], [NavigationCancel, '/user/victor'],
|
[NavigationStart, '/user/victor'],
|
||||||
|
[NavigationCancel, '/user/victor'],
|
||||||
|
|
||||||
[NavigationStart, '/user/fedor'], [RoutesRecognized, '/user/fedor'],
|
[NavigationStart, '/user/fedor'],
|
||||||
[GuardsCheckStart, '/user/fedor'], [ChildActivationStart],
|
[RoutesRecognized, '/user/fedor'],
|
||||||
[GuardsCheckEnd, '/user/fedor'], [ResolveStart, '/user/fedor'],
|
[GuardsCheckStart, '/user/fedor'],
|
||||||
[ResolveEnd, '/user/fedor'], [ChildActivationEnd],
|
[ChildActivationStart],
|
||||||
|
[ActivationStart],
|
||||||
|
[GuardsCheckEnd, '/user/fedor'],
|
||||||
|
[ResolveStart, '/user/fedor'],
|
||||||
|
[ResolveEnd, '/user/fedor'],
|
||||||
|
[ActivationEnd],
|
||||||
|
[ChildActivationEnd],
|
||||||
[NavigationEnd, '/user/fedor']
|
[NavigationEnd, '/user/fedor']
|
||||||
]);
|
]);
|
||||||
})));
|
})));
|
||||||
|
@ -743,8 +756,9 @@ describe('Integration', () => {
|
||||||
[NavigationStart, '/invalid'], [NavigationError, '/invalid'],
|
[NavigationStart, '/invalid'], [NavigationError, '/invalid'],
|
||||||
|
|
||||||
[NavigationStart, '/user/fedor'], [RoutesRecognized, '/user/fedor'],
|
[NavigationStart, '/user/fedor'], [RoutesRecognized, '/user/fedor'],
|
||||||
[GuardsCheckStart, '/user/fedor'], [ChildActivationStart], [GuardsCheckEnd, '/user/fedor'],
|
[GuardsCheckStart, '/user/fedor'], [ChildActivationStart], [ActivationStart],
|
||||||
[ResolveStart, '/user/fedor'], [ResolveEnd, '/user/fedor'], [ChildActivationEnd],
|
[GuardsCheckEnd, '/user/fedor'], [ResolveStart, '/user/fedor'],
|
||||||
|
[ResolveEnd, '/user/fedor'], [ActivationEnd], [ChildActivationEnd],
|
||||||
[NavigationEnd, '/user/fedor']
|
[NavigationEnd, '/user/fedor']
|
||||||
]);
|
]);
|
||||||
})));
|
})));
|
||||||
|
@ -925,6 +939,8 @@ describe('Integration', () => {
|
||||||
expect(cmp.path.length).toEqual(2);
|
expect(cmp.path.length).toEqual(2);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe('data', () => {
|
describe('data', () => {
|
||||||
class ResolveSix implements Resolve<number> {
|
class ResolveSix implements Resolve<number> {
|
||||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): number { return 6; }
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): number { return 6; }
|
||||||
|
@ -1465,11 +1481,15 @@ describe('Integration', () => {
|
||||||
|
|
||||||
expect(location.path()).toEqual('/');
|
expect(location.path()).toEqual('/');
|
||||||
expectEvents(recordedEvents, [
|
expectEvents(recordedEvents, [
|
||||||
[NavigationStart, '/team/22'], [RoutesRecognized, '/team/22'],
|
[NavigationStart, '/team/22'],
|
||||||
[GuardsCheckStart, '/team/22'], [ChildActivationStart], [GuardsCheckEnd, '/team/22'],
|
[RoutesRecognized, '/team/22'],
|
||||||
[NavigationCancel, '/team/22']
|
[GuardsCheckStart, '/team/22'],
|
||||||
|
[ChildActivationStart],
|
||||||
|
[ActivationStart],
|
||||||
|
[GuardsCheckEnd, '/team/22'],
|
||||||
|
[NavigationCancel, '/team/22'],
|
||||||
]);
|
]);
|
||||||
expect((recordedEvents[4] as GuardsCheckEnd).shouldActivate).toBe(false);
|
expect((recordedEvents[5] as GuardsCheckEnd).shouldActivate).toBe(false);
|
||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2392,11 +2412,15 @@ describe('Integration', () => {
|
||||||
[RoutesRecognized, '/lazyTrue/loaded'],
|
[RoutesRecognized, '/lazyTrue/loaded'],
|
||||||
[GuardsCheckStart, '/lazyTrue/loaded'],
|
[GuardsCheckStart, '/lazyTrue/loaded'],
|
||||||
[ChildActivationStart],
|
[ChildActivationStart],
|
||||||
|
[ActivationStart],
|
||||||
[ChildActivationStart],
|
[ChildActivationStart],
|
||||||
|
[ActivationStart],
|
||||||
[GuardsCheckEnd, '/lazyTrue/loaded'],
|
[GuardsCheckEnd, '/lazyTrue/loaded'],
|
||||||
[ResolveStart, '/lazyTrue/loaded'],
|
[ResolveStart, '/lazyTrue/loaded'],
|
||||||
[ResolveEnd, '/lazyTrue/loaded'],
|
[ResolveEnd, '/lazyTrue/loaded'],
|
||||||
|
[ActivationEnd],
|
||||||
[ChildActivationEnd],
|
[ChildActivationEnd],
|
||||||
|
[ActivationEnd],
|
||||||
[ChildActivationEnd],
|
[ChildActivationEnd],
|
||||||
[NavigationEnd, '/lazyTrue/loaded'],
|
[NavigationEnd, '/lazyTrue/loaded'],
|
||||||
]);
|
]);
|
||||||
|
@ -2428,9 +2452,9 @@ describe('Integration', () => {
|
||||||
[NavigationCancel, '/lazyFalse/loaded'],
|
[NavigationCancel, '/lazyFalse/loaded'],
|
||||||
|
|
||||||
[NavigationStart, '/blank'], [RoutesRecognized, '/blank'],
|
[NavigationStart, '/blank'], [RoutesRecognized, '/blank'],
|
||||||
[GuardsCheckStart, '/blank'], [ChildActivationStart], [GuardsCheckEnd, '/blank'],
|
[GuardsCheckStart, '/blank'], [ChildActivationStart], [ActivationStart],
|
||||||
[ResolveStart, '/blank'], [ResolveEnd, '/blank'], [ChildActivationEnd],
|
[GuardsCheckEnd, '/blank'], [ResolveStart, '/blank'], [ResolveEnd, '/blank'],
|
||||||
[NavigationEnd, '/blank']
|
[ActivationEnd], [ChildActivationEnd], [NavigationEnd, '/blank']
|
||||||
]);
|
]);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
@ -2562,6 +2586,40 @@ describe('Integration', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('route events', () => {
|
||||||
|
it('should fire matching (Child)ActivationStart/End events',
|
||||||
|
fakeAsync(inject([Router], (router: Router) => {
|
||||||
|
const fixture = createRoot(router, RootCmp);
|
||||||
|
|
||||||
|
router.resetConfig([{path: 'user/:name', component: UserCmp}]);
|
||||||
|
|
||||||
|
const recordedEvents: any[] = [];
|
||||||
|
router.events.forEach(e => recordedEvents.push(e));
|
||||||
|
|
||||||
|
router.navigateByUrl('/user/fedor');
|
||||||
|
advance(fixture);
|
||||||
|
|
||||||
|
expect(fixture.nativeElement).toHaveText('user fedor');
|
||||||
|
expect(recordedEvents[3] instanceof ChildActivationStart).toBe(true);
|
||||||
|
expect(recordedEvents[3].snapshot).toBe(recordedEvents[9].snapshot.root);
|
||||||
|
expect(recordedEvents[9] instanceof ChildActivationEnd).toBe(true);
|
||||||
|
expect(recordedEvents[9].snapshot).toBe(recordedEvents[9].snapshot.root);
|
||||||
|
|
||||||
|
expect(recordedEvents[4] instanceof ActivationStart).toBe(true);
|
||||||
|
expect(recordedEvents[4].snapshot.routeConfig.path).toBe('user/:name');
|
||||||
|
expect(recordedEvents[8] instanceof ActivationEnd).toBe(true);
|
||||||
|
expect(recordedEvents[8].snapshot.routeConfig.path).toBe('user/:name');
|
||||||
|
|
||||||
|
expectEvents(recordedEvents, [
|
||||||
|
[NavigationStart, '/user/fedor'], [RoutesRecognized, '/user/fedor'],
|
||||||
|
[GuardsCheckStart, '/user/fedor'], [ChildActivationStart], [ActivationStart],
|
||||||
|
[GuardsCheckEnd, '/user/fedor'], [ResolveStart, '/user/fedor'],
|
||||||
|
[ResolveEnd, '/user/fedor'], [ActivationEnd], [ChildActivationEnd],
|
||||||
|
[NavigationEnd, '/user/fedor']
|
||||||
|
]);
|
||||||
|
})));
|
||||||
|
});
|
||||||
|
|
||||||
describe('routerActiveLink', () => {
|
describe('routerActiveLink', () => {
|
||||||
it('should set the class when the link is active (a tag)',
|
it('should set the class when the link is active (a tag)',
|
||||||
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
|
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
|
||||||
|
|
|
@ -110,7 +110,9 @@ describe('Router', () => {
|
||||||
p.initalize(new ChildrenOutletContexts());
|
p.initalize(new ChildrenOutletContexts());
|
||||||
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
|
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
expect(events.length).toEqual(1);
|
expect(events.length).toEqual(2);
|
||||||
|
expect(events[0].snapshot).toBe(events[0].snapshot.root);
|
||||||
|
expect(events[1].snapshot.routeConfig.path).toBe('child');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run from top to bottom', () => {
|
it('should run from top to bottom', () => {
|
||||||
|
@ -142,10 +144,11 @@ describe('Router', () => {
|
||||||
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
|
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
expect(events.length).toEqual(3);
|
expect(events.length).toEqual(6);
|
||||||
expect(events[0].snapshot).toBe(events[0].snapshot.root);
|
expect(events[0].snapshot).toBe(events[0].snapshot.root);
|
||||||
expect(events[1].snapshot.routeConfig.path).toBe('child');
|
expect(events[2].snapshot.routeConfig.path).toBe('child');
|
||||||
expect(events[2].snapshot.routeConfig.path).toBe('grandchild');
|
expect(events[4].snapshot.routeConfig.path).toBe('grandchild');
|
||||||
|
expect(events[5].snapshot.routeConfig.path).toBe('great-grandchild');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not run for unchanged routes', () => {
|
it('should not run for unchanged routes', () => {
|
||||||
|
@ -174,7 +177,7 @@ describe('Router', () => {
|
||||||
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
|
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
expect(events.length).toEqual(1);
|
expect(events.length).toEqual(2);
|
||||||
expect(events[0].snapshot).not.toBe(events[0].snapshot.root);
|
expect(events[0].snapshot).not.toBe(events[0].snapshot.root);
|
||||||
expect(events[0].snapshot.routeConfig.path).toBe('child');
|
expect(events[0].snapshot.routeConfig.path).toBe('child');
|
||||||
});
|
});
|
||||||
|
@ -220,11 +223,11 @@ describe('Router', () => {
|
||||||
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
|
p.checkGuards().subscribe((x) => result = x, (e) => { throw e; });
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
expect(events.length).toEqual(2);
|
expect(events.length).toEqual(4);
|
||||||
expect(events[0] instanceof ChildActivationStart).toBe(true);
|
expect(events[0] instanceof ChildActivationStart).toBe(true);
|
||||||
expect(events[0].snapshot).not.toBe(events[0].snapshot.root);
|
expect(events[0].snapshot).not.toBe(events[0].snapshot.root);
|
||||||
expect(events[0].snapshot.routeConfig.path).toBe('grandchild');
|
expect(events[0].snapshot.routeConfig.path).toBe('grandchild');
|
||||||
expect(events[1].snapshot.routeConfig.path).toBe('greatgrandchild');
|
expect(events[2].snapshot.routeConfig.path).toBe('greatgrandchild');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,22 @@ export declare class ActivatedRouteSnapshot {
|
||||||
toString(): string;
|
toString(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @experimental */
|
||||||
|
export declare class ActivationEnd {
|
||||||
|
snapshot: ActivatedRouteSnapshot;
|
||||||
|
constructor(
|
||||||
|
snapshot: ActivatedRouteSnapshot);
|
||||||
|
toString(): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @experimental */
|
||||||
|
export declare class ActivationStart {
|
||||||
|
snapshot: ActivatedRouteSnapshot;
|
||||||
|
constructor(
|
||||||
|
snapshot: ActivatedRouteSnapshot);
|
||||||
|
toString(): string;
|
||||||
|
}
|
||||||
|
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export interface CanActivate {
|
export interface CanActivate {
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean;
|
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean;
|
||||||
|
@ -103,7 +119,7 @@ export declare class DefaultUrlSerializer implements UrlSerializer {
|
||||||
export declare type DetachedRouteHandle = {};
|
export declare type DetachedRouteHandle = {};
|
||||||
|
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export declare type Event = RouterEvent | RouteConfigLoadStart | RouteConfigLoadEnd | ChildActivationStart | ChildActivationEnd;
|
export declare type Event = RouterEvent | RouteConfigLoadStart | RouteConfigLoadEnd | ChildActivationStart | ChildActivationEnd | ActivationStart | ActivationEnd;
|
||||||
|
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export interface ExtraOptions {
|
export interface ExtraOptions {
|
||||||
|
|
Loading…
Reference in New Issue