From 86b7bd9c8e90b1b8f863abce162e081d49cde885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Thu, 18 May 2017 11:28:50 -0700 Subject: [PATCH] revert: refactor(router): cleanup, simplification This reverts commit 44d48d9d7aa10bbf03c412ce7e59821c748b5d2d. --- .../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, 161 insertions(+), 175 deletions(-) diff --git a/packages/router/src/directives/router_outlet.ts b/packages/router/src/directives/router_outlet.ts index 9c8082b8b6..a483fa5a9e 100644 --- a/packages/router/src/directives/router_outlet.ts +++ b/packages/router/src/directives/router_outlet.ts @@ -37,9 +37,8 @@ import {PRIMARY_OUTLET} from '../shared'; */ @Directive({selector: 'router-outlet'}) export class RouterOutlet implements OnDestroy { - private activated: ComponentRef|null = null; - private _activatedRoute: ActivatedRoute|null = null; - private _outletName: string; + private activated: ComponentRef; + private _activatedRoute: ActivatedRoute; public outletMap: RouterOutletMap; @Output('activate') activateEvents = new EventEmitter(); @@ -47,12 +46,11 @@ export class RouterOutlet implements OnDestroy { constructor( private parentOutletMap: RouterOutletMap, private location: ViewContainerRef, - private resolver: ComponentFactoryResolver, @Attribute('name') name: string) { - this._outletName = name || PRIMARY_OUTLET; - parentOutletMap.registerOutlet(this._outletName, this); + private resolver: ComponentFactoryResolver, @Attribute('name') private name: string) { + parentOutletMap.registerOutlet(name ? name : PRIMARY_OUTLET, this); } - ngOnDestroy(): void { this.parentOutletMap.removeOutlet(this._outletName); } + ngOnDestroy(): void { this.parentOutletMap.removeOutlet(this.name ? this.name : PRIMARY_OUTLET); } /** @deprecated since v4 **/ get locationInjector(): Injector { return this.location.injector; } @@ -60,32 +58,24 @@ 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 as ActivatedRoute; + return this._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 cmp = this.activated; - this.activated = null; - this._activatedRoute = null; - return cmp; + const r = this.activated; + this.activated = null !; + this._activatedRoute = null !; + return r; } - /** - * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree - */ attach(ref: ComponentRef, activatedRoute: ActivatedRoute) { this.activated = ref; this._activatedRoute = activatedRoute; @@ -96,8 +86,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); } } @@ -139,11 +129,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 e316fa1032..09ed8453b1 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.inheritParamsAndData(routeState._root); + this.inheriteParamsAndData(routeState._root); return of (routeState); } catch (e) { @@ -52,14 +52,14 @@ class Recognizer { } } - inheritParamsAndData(routeNode: TreeNode): void { + inheriteParamsAndData(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.inheritParamsAndData(n)); + routeNode.children.forEach(n => this.inheriteParamsAndData(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 45da2d6164..3f96768bef 100644 --- a/packages/router/src/route_reuse_strategy.ts +++ b/packages/router/src/route_reuse_strategy.ts @@ -47,17 +47,4 @@ export abstract class RouteReuseStrategy { /** Determines if a route should be reused */ abstract shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean; -} - -/** - * 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; - } -} +} \ No newline at end of file diff --git a/packages/router/src/router.ts b/packages/router/src/router.ts index 48b9f3f020..bca264097f 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 {DefaultRouteReuseStrategy, DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy'; +import {DetachedRouteHandle, 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,6 +192,19 @@ 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. * @@ -480,10 +493,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 { @@ -624,7 +637,6 @@ export class Router { // run preactivation: guards and data resolvers let preActivation: PreActivation; - const preactivationTraverse$ = map.call( beforePreactivationDone$, ({appliedUrl, snapshot}: {appliedUrl: string, snapshot: RouterStateSnapshot}) => { @@ -759,10 +771,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) {} @@ -796,16 +808,13 @@ 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.deactivateRouteAndItsChildren(v, outletMap !._outlets[k])); + this.deactiveRouteAndItsChildren(v, outletMap !._outlets[k])); } private traverseRoutes( @@ -838,7 +847,7 @@ export class PreActivation { } } else { if (curr) { - this.deactivateRouteAndItsChildren(currNode, outlet); + this.deactiveRouteAndItsChildren(currNode, outlet); } this.canActivateChecks.push(new CanActivate(futurePath)); @@ -870,18 +879,18 @@ export class PreActivation { } } - private deactivateRouteAndItsChildren( + private deactiveRouteAndItsChildren( route: TreeNode, outlet: RouterOutlet|null): void { const prevChildren = nodeChildrenAsMap(route); const r = route.value; forEach(prevChildren, (v: TreeNode, k: string) => { if (!r.component) { - this.deactivateRouteAndItsChildren(v, outlet); - } else if (outlet) { - this.deactivateRouteAndItsChildren(v, outlet.outletMap._outlets[k]); + this.deactiveRouteAndItsChildren(v, outlet); + } else if (!!outlet) { + this.deactiveRouteAndItsChildren(v, outlet.outletMap._outlets[k]); } else { - this.deactivateRouteAndItsChildren(v, null); + this.deactiveRouteAndItsChildren(v, null); } }); @@ -1011,112 +1020,74 @@ 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: {[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]; + const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode); + futureNode.children.forEach(c => { + this.deactivateRoutes(c, prevChildren[c.value.outlet], outletMap); + delete prevChildren[c.value.outlet]; }); - - // 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(); + forEach(prevChildren, (v: any, k: string) => this.deactiveRouteAndItsChildren(v, outletMap)); } private activateChildRoutes( futureNode: TreeNode, currNode: TreeNode|null, outletMap: RouterOutletMap): void { - const prevChildren: {[outlet: string]: any} = nodeChildrenAsMap(currNode); + const prevChildren: {[key: string]: any} = nodeChildrenAsMap(currNode); futureNode.children.forEach( c => { this.activateRoutes(c, prevChildren[c.value.outlet], outletMap); }); } - private activateRoutes( + deactivateRoutes( 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) { + // 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; // 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); - } else { + // if we have a componentless route, we recurse but keep the same outlet map. + } else { 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) { - // if we have a normal route, we need to place the component into the outlet and recurse. + advanceActivatedRoute(future); const outlet = getOutlet(parentOutletMap, futureNode.value); if (this.routeReuseStrategy.shouldAttach(future.snapshot)) { @@ -1130,8 +1101,10 @@ class ActivateRoutes { this.placeComponentIntoOutlet(outletMap, future, outlet); this.activateChildRoutes(futureNode, null, outletMap); } - } else { + // if we have a componentless route, we recurse but keep the same outlet map. + } else { + advanceActivatedRoute(future); this.activateChildRoutes(futureNode, null, parentOutletMap); } } @@ -1144,6 +1117,49 @@ 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 { @@ -1172,9 +1188,8 @@ function closestLoadedConfig(snapshot: ActivatedRouteSnapshot): LoadedRouterConf return null; } -// Return the list of T indexed by outlet name function nodeChildrenAsMap(node: TreeNode| null) { - const map: {[outlet: string]: TreeNode} = {}; + const map: {[key: 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 f70bc0e814..3fb1ad7a12 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 as any; } + removeOutlet(name: string): void { this._outlets[name] = undefined !; } } diff --git a/packages/router/src/router_state.ts b/packages/router/src/router_state.ts index 8008d68e1a..7b2f33be80 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); - setRouterState(this, root); + setRouterStateSnapshot(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); - setRouterState(this, root); + setRouterStateSnapshot(this, root); } toString(): string { return serializeNode(this._root); } } -function setRouterState(state: U, node: TreeNode): void { +function setRouterStateSnapshot(state: U, node: TreeNode): void { node.value._routerState = state; - node.children.forEach(c => setRouterState(state, c)); + node.children.forEach(c => setRouterStateSnapshot(state, c)); } function serializeNode(node: TreeNode): string { @@ -367,22 +367,21 @@ function serializeNode(node: TreeNode): string { export function advanceActivatedRoute(route: ActivatedRoute): void { if (route.snapshot) { const currentSnapshot = route.snapshot; - const nextSnapshot = route._futureSnapshot; - route.snapshot = nextSnapshot; - if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) { - (route.queryParams).next(nextSnapshot.queryParams); + route.snapshot = route._futureSnapshot; + if (!shallowEqual(currentSnapshot.queryParams, route._futureSnapshot.queryParams)) { + (route.queryParams).next(route._futureSnapshot.queryParams); } - if (currentSnapshot.fragment !== nextSnapshot.fragment) { - (route.fragment).next(nextSnapshot.fragment); + if (currentSnapshot.fragment !== route._futureSnapshot.fragment) { + (route.fragment).next(route._futureSnapshot.fragment); } - if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) { - (route.params).next(nextSnapshot.params); + if (!shallowEqual(currentSnapshot.params, route._futureSnapshot.params)) { + (route.params).next(route._futureSnapshot.params); } - if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) { - (route.url).next(nextSnapshot.url); + if (!shallowEqualArrays(currentSnapshot.url, route._futureSnapshot.url)) { + (route.url).next(route._futureSnapshot.url); } - if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) { - (route.data).next(nextSnapshot.data); + if (!shallowEqual(currentSnapshot.data, route._futureSnapshot.data)) { + (route.data).next(route._futureSnapshot.data); } } else { route.snapshot = route._futureSnapshot; diff --git a/packages/router/src/utils/tree.ts b/packages/router/src/utils/tree.ts index bcb6037e62..a21fee00ed 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,32 +52,26 @@ 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); } } - -// 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; +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; } - return null; } -// 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]; +function findPath(expected: T, c: TreeNode, collected: TreeNode[]): TreeNode[] { + collected.push(c); + if (expected === c.value) return collected; - for (const child of node.children) { - const path = findPath(value, child); - if (path.length) { - path.unshift(node); - return path; - } + for (const cc of c.children) { + const cloned = collected.slice(0); + const r = findPath(expected, cc, cloned); + if (r.length > 0) return r; } return []; diff --git a/packages/router/test/create_router_state.spec.ts b/packages/router/test/create_router_state.spec.ts index 9c87327aff..49ed70f028 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/route_reuse_strategy'; +import {DefaultRouteReuseStrategy} from '../src/router'; 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,6 +80,7 @@ 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'});