From 92a5876f5112f500263843ffbd291c1e5a61f276 Mon Sep 17 00:00:00 2001 From: Dan Bucholtz Date: Mon, 5 Feb 2018 16:11:59 -0600 Subject: [PATCH] refactor(router): move activation to private method (#22033) PR Close #22033 --- packages/router/src/router.ts | 148 ++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 69 deletions(-) diff --git a/packages/router/src/router.ts b/packages/router/src/router.ts index 952ead4a29..330f4ed1cc 100644 --- a/packages/router/src/router.ts +++ b/packages/router/src/router.ts @@ -712,78 +712,88 @@ export class Router { } }); - - // applied the new router state - // this operation has side effects - let navigationIsSuccessful: boolean; - const storedState = this.routerState; - const storedUrl = this.currentUrlTree; - - routerState$ - .forEach(({appliedUrl, state, shouldActivate}: any) => { - if (!shouldActivate || id !== this.navigationId) { - navigationIsSuccessful = false; - return; - } - - this.currentUrlTree = appliedUrl; - this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl); - - (this as{routerState: RouterState}).routerState = state; - - if (!skipLocationChange) { - const path = this.urlSerializer.serialize(this.rawUrlTree); - if (this.location.isCurrentPathEqualTo(path) || replaceUrl) { - this.location.replaceState(path, '', {navigationId: id}); - } else { - this.location.go(path, '', {navigationId: id}); - } - } - - new ActivateRoutes( - this.routeReuseStrategy, state, storedState, (evt: Event) => this.triggerEvent(evt)) - .activate(this.rootContexts); - - navigationIsSuccessful = true; - }) - .then( - () => { - if (navigationIsSuccessful) { - this.navigated = true; - this.lastSuccessfulId = id; - (this.events as Subject) - .next(new NavigationEnd( - id, this.serializeUrl(url), this.serializeUrl(this.currentUrlTree))); - resolvePromise(true); - } else { - this.resetUrlToCurrentUrlTree(); - (this.events as Subject) - .next(new NavigationCancel(id, this.serializeUrl(url), '')); - resolvePromise(false); - } - }, - (e: any) => { - if (isNavigationCancelingError(e)) { - this.navigated = true; - this.resetStateAndUrl(storedState, storedUrl, rawUrl); - (this.events as Subject) - .next(new NavigationCancel(id, this.serializeUrl(url), e.message)); - - resolvePromise(false); - } else { - this.resetStateAndUrl(storedState, storedUrl, rawUrl); - (this.events as Subject) - .next(new NavigationError(id, this.serializeUrl(url), e)); - try { - resolvePromise(this.errorHandler(e)); - } catch (ee) { - rejectPromise(ee); - } - } - }); + this.activateRoutes( + routerState$, this.routerState, this.currentUrlTree, id, url, rawUrl, skipLocationChange, + replaceUrl, resolvePromise, rejectPromise); }); } + /** + * Performs the logic of activating routes. This is a synchronous process by default. While this + * is a private method, it could be overridden to make activation asynchronous. + */ + private activateRoutes( + state: Observable<{appliedUrl: string, state: RouterState, shouldActivate: boolean}>, + storedState: RouterState, storedUrl: UrlTree, id: number, url: UrlTree, rawUrl: UrlTree, + skipLocationChange: boolean, replaceUrl: boolean, resolvePromise: any, rejectPromise: any) { + // applied the new router state + // this operation has side effects + let navigationIsSuccessful: boolean; + + state + .forEach(({appliedUrl, state, shouldActivate}: any) => { + if (!shouldActivate || id !== this.navigationId) { + navigationIsSuccessful = false; + return; + } + + this.currentUrlTree = appliedUrl; + this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl); + + (this as{routerState: RouterState}).routerState = state; + + if (!skipLocationChange) { + const path = this.urlSerializer.serialize(this.rawUrlTree); + if (this.location.isCurrentPathEqualTo(path) || replaceUrl) { + this.location.replaceState(path, '', {navigationId: id}); + } else { + this.location.go(path, '', {navigationId: id}); + } + } + + new ActivateRoutes( + this.routeReuseStrategy, state, storedState, (evt: Event) => this.triggerEvent(evt)) + .activate(this.rootContexts); + + navigationIsSuccessful = true; + }) + .then( + () => { + if (navigationIsSuccessful) { + this.navigated = true; + this.lastSuccessfulId = id; + (this.events as Subject) + .next(new NavigationEnd( + id, this.serializeUrl(url), this.serializeUrl(this.currentUrlTree))); + resolvePromise(true); + } else { + this.resetUrlToCurrentUrlTree(); + (this.events as Subject) + .next(new NavigationCancel(id, this.serializeUrl(url), '')); + resolvePromise(false); + } + }, + (e: any) => { + if (isNavigationCancelingError(e)) { + this.navigated = true; + this.resetStateAndUrl(storedState, storedUrl, rawUrl); + (this.events as Subject) + .next(new NavigationCancel(id, this.serializeUrl(url), e.message)); + + resolvePromise(false); + } else { + this.resetStateAndUrl(storedState, storedUrl, rawUrl); + (this.events as Subject) + .next(new NavigationError(id, this.serializeUrl(url), e)); + try { + resolvePromise(this.errorHandler(e)); + } catch (ee) { + rejectPromise(ee); + } + } + }); + } + private resetStateAndUrl(storedState: RouterState, storedUrl: UrlTree, rawUrl: UrlTree): void { (this as{routerState: RouterState}).routerState = storedState; this.currentUrlTree = storedUrl;