From 44d48d9d7aa10bbf03c412ce7e59821c748b5d2d Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Wed, 3 May 2017 11:17:27 +0200 Subject: [PATCH] refactor(router): cleanup, simplification --- .../router/src/directives/router_outlet.ts | 38 ++-- packages/router/src/recognize.ts | 6 +- packages/router/src/route_reuse_strategy.ts | 15 +- packages/router/src/router.ts | 207 ++++++++---------- packages/router/src/router_outlet_map.ts | 2 +- packages/router/src/router_state.ts | 31 +-- packages/router/src/utils/tree.ts | 34 +-- .../router/test/create_router_state.spec.ts | 3 +- 8 files changed, 175 insertions(+), 161 deletions(-) diff --git a/packages/router/src/directives/router_outlet.ts b/packages/router/src/directives/router_outlet.ts index a483fa5a9e..9c8082b8b6 100644 --- a/packages/router/src/directives/router_outlet.ts +++ b/packages/router/src/directives/router_outlet.ts @@ -37,8 +37,9 @@ import {PRIMARY_OUTLET} from '../shared'; */ @Directive({selector: 'router-outlet'}) export class RouterOutlet implements OnDestroy { - private activated: ComponentRef; - private _activatedRoute: ActivatedRoute; + private activated: ComponentRef|null = null; + private _activatedRoute: ActivatedRoute|null = null; + private _outletName: string; public outletMap: RouterOutletMap; @Output('activate') activateEvents = new EventEmitter(); @@ -46,11 +47,12 @@ export class RouterOutlet implements OnDestroy { constructor( private parentOutletMap: RouterOutletMap, private location: ViewContainerRef, - private resolver: ComponentFactoryResolver, @Attribute('name') private name: string) { - parentOutletMap.registerOutlet(name ? name : PRIMARY_OUTLET, this); + private resolver: ComponentFactoryResolver, @Attribute('name') name: string) { + this._outletName = name || PRIMARY_OUTLET; + parentOutletMap.registerOutlet(this._outletName, this); } - ngOnDestroy(): void { this.parentOutletMap.removeOutlet(this.name ? this.name : PRIMARY_OUTLET); } + ngOnDestroy(): void { this.parentOutletMap.removeOutlet(this._outletName); } /** @deprecated since v4 **/ get locationInjector(): Injector { return this.location.injector; } @@ -58,24 +60,32 @@ export class RouterOutlet implements OnDestroy { get locationFactoryResolver(): ComponentFactoryResolver { return this.resolver; } get isActivated(): boolean { return !!this.activated; } + get component(): Object { if (!this.activated) throw new Error('Outlet is not activated'); return this.activated.instance; } + get activatedRoute(): ActivatedRoute { if (!this.activated) throw new Error('Outlet is not activated'); - return this._activatedRoute; + return this._activatedRoute as ActivatedRoute; } + /** + * Called when the `RouteReuseStrategy` instructs to detach the subtree + */ detach(): ComponentRef { if (!this.activated) throw new Error('Outlet is not activated'); this.location.detach(); - const r = this.activated; - this.activated = null !; - this._activatedRoute = null !; - return r; + const cmp = this.activated; + this.activated = null; + this._activatedRoute = null; + return cmp; } + /** + * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree + */ attach(ref: ComponentRef, activatedRoute: ActivatedRoute) { this.activated = ref; this._activatedRoute = activatedRoute; @@ -86,8 +96,8 @@ export class RouterOutlet implements OnDestroy { if (this.activated) { const c = this.component; this.activated.destroy(); - this.activated = null !; - this._activatedRoute = null !; + this.activated = null; + this._activatedRoute = null; this.deactivateEvents.emit(c); } } @@ -129,11 +139,11 @@ export class RouterOutlet implements OnDestroy { const component = snapshot._routeConfig !.component; resolver = resolver || this.resolver; - const factory = resolver.resolveComponentFactory(component) !; + const factory = resolver.resolveComponentFactory(component); const injector = new OutletInjector(activatedRoute, outletMap, this.location.injector); - this.activated = this.location.createComponent(factory, this.location.length, injector, []); + this.activated = this.location.createComponent(factory, this.location.length, injector); this.activated.changeDetectorRef.detectChanges(); this.activateEvents.emit(this.activated.instance); diff --git a/packages/router/src/recognize.ts b/packages/router/src/recognize.ts index 09ed8453b1..e316fa1032 100644 --- a/packages/router/src/recognize.ts +++ b/packages/router/src/recognize.ts @@ -43,7 +43,7 @@ class Recognizer { const rootNode = new TreeNode(root, children); const routeState = new RouterStateSnapshot(this.url, rootNode); - this.inheriteParamsAndData(routeState._root); + this.inheritParamsAndData(routeState._root); return of (routeState); } catch (e) { @@ -52,14 +52,14 @@ class Recognizer { } } - inheriteParamsAndData(routeNode: TreeNode): void { + inheritParamsAndData(routeNode: TreeNode): void { const route = routeNode.value; const i = inheritedParamsDataResolve(route); route.params = Object.freeze(i.params); route.data = Object.freeze(i.data); - routeNode.children.forEach(n => this.inheriteParamsAndData(n)); + routeNode.children.forEach(n => this.inheritParamsAndData(n)); } processSegmentGroup(config: Route[], segmentGroup: UrlSegmentGroup, outlet: string): diff --git a/packages/router/src/route_reuse_strategy.ts b/packages/router/src/route_reuse_strategy.ts index 3f96768bef..45da2d6164 100644 --- a/packages/router/src/route_reuse_strategy.ts +++ b/packages/router/src/route_reuse_strategy.ts @@ -47,4 +47,17 @@ export abstract class RouteReuseStrategy { /** Determines if a route should be reused */ abstract shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean; -} \ No newline at end of file +} + +/** + * Does not detach any subtrees. Reuses routes as long as their route config is the same. + */ +export class DefaultRouteReuseStrategy implements RouteReuseStrategy { + shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; } + store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {} + shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; } + retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle|null { return null; } + shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { + return future.routeConfig === curr.routeConfig; + } +} diff --git a/packages/router/src/router.ts b/packages/router/src/router.ts index bca264097f..48b9f3f020 100644 --- a/packages/router/src/router.ts +++ b/packages/router/src/router.ts @@ -28,7 +28,7 @@ import {createUrlTree} from './create_url_tree'; import {RouterOutlet} from './directives/router_outlet'; import {Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, RouteConfigLoadEnd, RouteConfigLoadStart, RoutesRecognized} from './events'; import {recognize} from './recognize'; -import {DetachedRouteHandle, DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy'; +import {DefaultRouteReuseStrategy, DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy'; import {RouterConfigLoader} from './router_config_loader'; import {RouterOutletMap} from './router_outlet_map'; import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState, equalParamsAndUrlSegments, inheritedParamsDataResolve} from './router_state'; @@ -192,19 +192,6 @@ function defaultRouterHook(snapshot: RouterStateSnapshot): Observable { return of (null) as any; } -/** - * Does not detach any subtrees. Reuses routes as long as their route config is the same. - */ -export class DefaultRouteReuseStrategy implements RouteReuseStrategy { - shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; } - store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {} - shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; } - retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle|null { return null; } - shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { - return future.routeConfig === curr.routeConfig; - } -} - /** * @whatItDoes Provides the navigation and url manipulation capabilities. * @@ -493,10 +480,10 @@ export class Router { isActive(url: string|UrlTree, exact: boolean): boolean { if (url instanceof UrlTree) { return containsTree(this.currentUrlTree, url, exact); - } else { - const urlTree = this.urlSerializer.parse(url); - return containsTree(this.currentUrlTree, urlTree, exact); } + + const urlTree = this.urlSerializer.parse(url); + return containsTree(this.currentUrlTree, urlTree, exact); } private removeEmptyProps(params: Params): Params { @@ -637,6 +624,7 @@ export class Router { // run preactivation: guards and data resolvers let preActivation: PreActivation; + const preactivationTraverse$ = map.call( beforePreactivationDone$, ({appliedUrl, snapshot}: {appliedUrl: string, snapshot: RouterStateSnapshot}) => { @@ -771,10 +759,10 @@ class CanDeactivate { constructor(public component: Object|null, public route: ActivatedRouteSnapshot) {} } - export class PreActivation { private canActivateChecks: CanActivate[] = []; private canDeactivateChecks: CanDeactivate[] = []; + constructor( private future: RouterStateSnapshot, private curr: RouterStateSnapshot, private moduleInjector: Injector) {} @@ -808,13 +796,16 @@ export class PreActivation { outletMap: RouterOutletMap|null, futurePath: ActivatedRouteSnapshot[]): void { const prevChildren = nodeChildrenAsMap(currNode); + // Process the children of the future route futureNode.children.forEach(c => { this.traverseRoutes(c, prevChildren[c.value.outlet], outletMap, futurePath.concat([c.value])); delete prevChildren[c.value.outlet]; }); + + // Process any children left from the current route (not active for the future route) forEach( prevChildren, (v: TreeNode, k: string) => - this.deactiveRouteAndItsChildren(v, outletMap !._outlets[k])); + this.deactivateRouteAndItsChildren(v, outletMap !._outlets[k])); } private traverseRoutes( @@ -847,7 +838,7 @@ export class PreActivation { } } else { if (curr) { - this.deactiveRouteAndItsChildren(currNode, outlet); + this.deactivateRouteAndItsChildren(currNode, outlet); } this.canActivateChecks.push(new CanActivate(futurePath)); @@ -879,18 +870,18 @@ export class PreActivation { } } - private deactiveRouteAndItsChildren( + private deactivateRouteAndItsChildren( route: TreeNode, outlet: RouterOutlet|null): void { const prevChildren = nodeChildrenAsMap(route); const r = route.value; forEach(prevChildren, (v: TreeNode, k: string) => { if (!r.component) { - this.deactiveRouteAndItsChildren(v, outlet); - } else if (!!outlet) { - this.deactiveRouteAndItsChildren(v, outlet.outletMap._outlets[k]); + this.deactivateRouteAndItsChildren(v, outlet); + } else if (outlet) { + this.deactivateRouteAndItsChildren(v, outlet.outletMap._outlets[k]); } else { - this.deactiveRouteAndItsChildren(v, null); + this.deactivateRouteAndItsChildren(v, null); } }); @@ -1020,74 +1011,112 @@ class ActivateRoutes { this.activateChildRoutes(futureRoot, currRoot, parentOutletMap); } + // De-activate the child route that are not re-used for the future state private deactivateChildRoutes( futureNode: TreeNode, currNode: TreeNode|null, outletMap: RouterOutletMap): void { - const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode); - futureNode.children.forEach(c => { - this.deactivateRoutes(c, prevChildren[c.value.outlet], outletMap); - delete prevChildren[c.value.outlet]; + const prevChildren: {[outlet: string]: any} = nodeChildrenAsMap(currNode); + + // Recurse on the routes active in the future state to de-activate deeper children + futureNode.children.forEach(child => { + const childOutletName = child.value.outlet; + this.deactivateRoutes(child, prevChildren[childOutletName], outletMap); + delete prevChildren[childOutletName]; }); - forEach(prevChildren, (v: any, k: string) => this.deactiveRouteAndItsChildren(v, outletMap)); + + // De-activate the routes that will not be re-used + forEach(prevChildren, (v: any, k: string) => this.deactivateRouteAndItsChildren(v, outletMap)); + } + + private deactivateRoutes( + futureNode: TreeNode, currNode: TreeNode, + parentOutletMap: RouterOutletMap): void { + const future = futureNode.value; + const curr = currNode ? currNode.value : null; + + if (future === curr) { + // Reusing the node, check to see of the children need to be de-activated + if (future.component) { + // If we have a normal route, we need to go through an outlet. + const outlet = getOutlet(parentOutletMap, future); + this.deactivateChildRoutes(futureNode, currNode, outlet.outletMap); + } else { + // if we have a componentless route, we recurse but keep the same outlet map. + this.deactivateChildRoutes(futureNode, currNode, parentOutletMap); + } + } else { + if (curr) { + this.deactivateRouteAndItsChildren(currNode, parentOutletMap); + } + } + } + + private deactivateRouteAndItsChildren( + route: TreeNode, parentOutletMap: RouterOutletMap): void { + if (this.routeReuseStrategy.shouldDetach(route.value.snapshot)) { + this.detachAndStoreRouteSubtree(route, parentOutletMap); + } else { + this.deactivateRouteAndOutlet(route, parentOutletMap); + } + } + + private detachAndStoreRouteSubtree( + route: TreeNode, parentOutletMap: RouterOutletMap): void { + const outlet = getOutlet(parentOutletMap, route.value); + const componentRef = outlet.detach(); + this.routeReuseStrategy.store(route.value.snapshot, {componentRef, route}); + } + + private deactivateRouteAndOutlet( + route: TreeNode, parentOutletMap: RouterOutletMap): void { + const prevChildren: {[outletName: string]: any} = nodeChildrenAsMap(route); + let outlet: RouterOutlet; + + // getOutlet throws when cannot find the right outlet, + // which can happen if an outlet was in an NgIf and was removed + try { + outlet = getOutlet(parentOutletMap, route.value); + } catch (e) { + return; + } + + const outletMap = route.value.component ? outlet.outletMap : parentOutletMap; + + forEach( + prevChildren, (v: any, k: string) => { this.deactivateRouteAndItsChildren(v, outletMap); }); + + outlet.deactivate(); } private activateChildRoutes( futureNode: TreeNode, currNode: TreeNode|null, outletMap: RouterOutletMap): void { - const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode); + const prevChildren: {[outlet: string]: any} = nodeChildrenAsMap(currNode); futureNode.children.forEach( c => { this.activateRoutes(c, prevChildren[c.value.outlet], outletMap); }); } - deactivateRoutes( + private activateRoutes( futureNode: TreeNode, currNode: TreeNode, parentOutletMap: RouterOutletMap): void { const future = futureNode.value; const curr = currNode ? currNode.value : null; - // reusing the node - if (future === curr) { - // If we have a normal route, we need to go through an outlet. - if (future.component) { - const outlet = getOutlet(parentOutletMap, future); - this.deactivateChildRoutes(futureNode, currNode, outlet.outletMap); - - // if we have a componentless route, we recurse but keep the same outlet map. - } else { - this.deactivateChildRoutes(futureNode, currNode, parentOutletMap); - } - } else { - if (curr) { - this.deactiveRouteAndItsChildren(currNode, parentOutletMap); - } - } - } - - activateRoutes( - futureNode: TreeNode, currNode: TreeNode, - parentOutletMap: RouterOutletMap): void { - const future = futureNode.value; - const curr = currNode ? currNode.value : null; + advanceActivatedRoute(future); // reusing the node if (future === curr) { - // advance the route to push the parameters - advanceActivatedRoute(future); - - // If we have a normal route, we need to go through an outlet. if (future.component) { + // If we have a normal route, we need to go through an outlet. const outlet = getOutlet(parentOutletMap, future); this.activateChildRoutes(futureNode, currNode, outlet.outletMap); - - // if we have a componentless route, we recurse but keep the same outlet map. } else { + // if we have a componentless route, we recurse but keep the same outlet map. this.activateChildRoutes(futureNode, currNode, parentOutletMap); } } else { - // if we have a normal route, we need to advance the route - // and place the component into the outlet. After that recurse. if (future.component) { - advanceActivatedRoute(future); + // if we have a normal route, we need to place the component into the outlet and recurse. const outlet = getOutlet(parentOutletMap, futureNode.value); if (this.routeReuseStrategy.shouldAttach(future.snapshot)) { @@ -1101,10 +1130,8 @@ class ActivateRoutes { this.placeComponentIntoOutlet(outletMap, future, outlet); this.activateChildRoutes(futureNode, null, outletMap); } - - // if we have a componentless route, we recurse but keep the same outlet map. } else { - advanceActivatedRoute(future); + // if we have a componentless route, we recurse but keep the same outlet map. this.activateChildRoutes(futureNode, null, parentOutletMap); } } @@ -1117,49 +1144,6 @@ class ActivateRoutes { outlet.activateWith(future, cmpFactoryResolver, outletMap); } - - private deactiveRouteAndItsChildren( - route: TreeNode, parentOutletMap: RouterOutletMap): void { - if (this.routeReuseStrategy.shouldDetach(route.value.snapshot)) { - this.detachAndStoreRouteSubtree(route, parentOutletMap); - } else { - this.deactiveRouteAndOutlet(route, parentOutletMap); - } - } - - private detachAndStoreRouteSubtree( - route: TreeNode, parentOutletMap: RouterOutletMap): void { - const outlet = getOutlet(parentOutletMap, route.value); - const componentRef = outlet.detach(); - this.routeReuseStrategy.store(route.value.snapshot, {componentRef, route}); - } - - private deactiveRouteAndOutlet(route: TreeNode, parentOutletMap: RouterOutletMap): - void { - const prevChildren: {[key: string]: any} = nodeChildrenAsMap(route); - let outlet: RouterOutlet|null = null; - - // getOutlet throws when cannot find the right outlet, - // which can happen if an outlet was in an NgIf and was removed - try { - outlet = getOutlet(parentOutletMap, route.value); - } catch (e) { - return; - } - const childOutletMap = outlet.outletMap; - - forEach(prevChildren, (v: any, k: string) => { - if (route.value.component) { - this.deactiveRouteAndItsChildren(v, childOutletMap); - } else { - this.deactiveRouteAndItsChildren(v, parentOutletMap); - } - }); - - if (outlet && outlet.isActivated) { - outlet.deactivate(); - } - } } function advanceActivatedRouteNodeAndItsChildren(node: TreeNode): void { @@ -1188,8 +1172,9 @@ function closestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConf return null; } +// Return the list of T indexed by outlet name function nodeChildrenAsMap(node: TreeNode| null) { - const map: {[key: string]: TreeNode} = {}; + const map: {[outlet: string]: TreeNode} = {}; if (node) { node.children.forEach(child => map[child.value.outlet] = child); diff --git a/packages/router/src/router_outlet_map.ts b/packages/router/src/router_outlet_map.ts index 3fb1ad7a12..f70bc0e814 100644 --- a/packages/router/src/router_outlet_map.ts +++ b/packages/router/src/router_outlet_map.ts @@ -25,5 +25,5 @@ export class RouterOutletMap { /** * Removes an outlet from this map. */ - removeOutlet(name: string): void { this._outlets[name] = undefined !; } + removeOutlet(name: string): void { this._outlets[name] = undefined as any; } } diff --git a/packages/router/src/router_state.ts b/packages/router/src/router_state.ts index 7b2f33be80..8008d68e1a 100644 --- a/packages/router/src/router_state.ts +++ b/packages/router/src/router_state.ts @@ -51,7 +51,7 @@ export class RouterState extends Tree { /** The current snapshot of the router state */ public snapshot: RouterStateSnapshot) { super(root); - setRouterStateSnapshot(this, root); + setRouterState(this, root); } toString(): string { return this.snapshot.toString(); } @@ -343,15 +343,15 @@ export class RouterStateSnapshot extends Tree { /** The url from which this snapshot was created */ public url: string, root: TreeNode) { super(root); - setRouterStateSnapshot(this, root); + setRouterState(this, root); } toString(): string { return serializeNode(this._root); } } -function setRouterStateSnapshot(state: U, node: TreeNode): void { +function setRouterState(state: U, node: TreeNode): void { node.value._routerState = state; - node.children.forEach(c => setRouterStateSnapshot(state, c)); + node.children.forEach(c => setRouterState(state, c)); } function serializeNode(node: TreeNode): string { @@ -367,21 +367,22 @@ function serializeNode(node: TreeNode): string { export function advanceActivatedRoute(route: ActivatedRoute): void { if (route.snapshot) { const currentSnapshot = route.snapshot; - route.snapshot = route._futureSnapshot; - if (!shallowEqual(currentSnapshot.queryParams, route._futureSnapshot.queryParams)) { - (route.queryParams).next(route._futureSnapshot.queryParams); + const nextSnapshot = route._futureSnapshot; + route.snapshot = nextSnapshot; + if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) { + (route.queryParams).next(nextSnapshot.queryParams); } - if (currentSnapshot.fragment !== route._futureSnapshot.fragment) { - (route.fragment).next(route._futureSnapshot.fragment); + if (currentSnapshot.fragment !== nextSnapshot.fragment) { + (route.fragment).next(nextSnapshot.fragment); } - if (!shallowEqual(currentSnapshot.params, route._futureSnapshot.params)) { - (route.params).next(route._futureSnapshot.params); + if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) { + (route.params).next(nextSnapshot.params); } - if (!shallowEqualArrays(currentSnapshot.url, route._futureSnapshot.url)) { - (route.url).next(route._futureSnapshot.url); + if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) { + (route.url).next(nextSnapshot.url); } - if (!shallowEqual(currentSnapshot.data, route._futureSnapshot.data)) { - (route.data).next(route._futureSnapshot.data); + if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) { + (route.data).next(nextSnapshot.data); } } else { route.snapshot = route._futureSnapshot; diff --git a/packages/router/src/utils/tree.ts b/packages/router/src/utils/tree.ts index a21fee00ed..bcb6037e62 100644 --- a/packages/router/src/utils/tree.ts +++ b/packages/router/src/utils/tree.ts @@ -42,7 +42,7 @@ export class Tree { * @internal */ siblings(t: T): T[] { - const p = findPath(t, this._root, []); + const p = findPath(t, this._root); if (p.length < 2) return []; const c = p[p.length - 2].children.map(c => c.value); @@ -52,26 +52,32 @@ export class Tree { /** * @internal */ - pathFromRoot(t: T): T[] { return findPath(t, this._root, []).map(s => s.value); } + pathFromRoot(t: T): T[] { return findPath(t, this._root).map(s => s.value); } } -function findNode(expected: T, c: TreeNode): TreeNode|null { - if (expected === c.value) return c; - for (const cc of c.children) { - const r = findNode(expected, cc); - if (r) return r; + +// DFS for the node matching the value +function findNode(value: T, node: TreeNode): TreeNode|null { + if (value === node.value) return node; + + for (const child of node.children) { + const node = findNode(value, child); + if (node) return node; } + return null; } -function findPath(expected: T, c: TreeNode, collected: TreeNode[]): TreeNode[] { - collected.push(c); - if (expected === c.value) return collected; +// Return the path to the node with the given value using DFS +function findPath(value: T, node: TreeNode): TreeNode[] { + if (value === node.value) return [node]; - for (const cc of c.children) { - const cloned = collected.slice(0); - const r = findPath(expected, cc, cloned); - if (r.length > 0) return r; + for (const child of node.children) { + const path = findPath(value, child); + if (path.length) { + path.unshift(node); + return path; + } } return []; diff --git a/packages/router/test/create_router_state.spec.ts b/packages/router/test/create_router_state.spec.ts index 49ed70f028..9c87327aff 100644 --- a/packages/router/test/create_router_state.spec.ts +++ b/packages/router/test/create_router_state.spec.ts @@ -9,7 +9,7 @@ import {Routes} from '../src/config'; import {createRouterState} from '../src/create_router_state'; import {recognize} from '../src/recognize'; -import {DefaultRouteReuseStrategy} from '../src/router'; +import {DefaultRouteReuseStrategy} from '../src/route_reuse_strategy'; import {ActivatedRoute, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState} from '../src/router_state'; import {PRIMARY_OUTLET} from '../src/shared'; import {DefaultUrlSerializer, UrlSegmentGroup, UrlTree} from '../src/url_tree'; @@ -80,7 +80,6 @@ describe('create router state', () => { const currP = state.firstChild(state.root) !; expect(prevP).toBe(currP); - const prevC = prevState.children(prevP); const currC = state.children(currP); expect(currP._futureSnapshot.params).toEqual({id: '2', p: '22'});