refactor(router): move activation to private method (#22033)

PR Close #22033
This commit is contained in:
Dan Bucholtz 2018-02-05 16:11:59 -06:00 committed by Miško Hevery
parent a57df4ee20
commit 92a5876f51
1 changed files with 79 additions and 69 deletions

View File

@ -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<Event>)
.next(new NavigationEnd(
id, this.serializeUrl(url), this.serializeUrl(this.currentUrlTree)));
resolvePromise(true);
} else {
this.resetUrlToCurrentUrlTree();
(this.events as Subject<Event>)
.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<Event>)
.next(new NavigationCancel(id, this.serializeUrl(url), e.message));
resolvePromise(false);
} else {
this.resetStateAndUrl(storedState, storedUrl, rawUrl);
(this.events as Subject<Event>)
.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<Event>)
.next(new NavigationEnd(
id, this.serializeUrl(url), this.serializeUrl(this.currentUrlTree)));
resolvePromise(true);
} else {
this.resetUrlToCurrentUrlTree();
(this.events as Subject<Event>)
.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<Event>)
.next(new NavigationCancel(id, this.serializeUrl(url), e.message));
resolvePromise(false);
} else {
this.resetStateAndUrl(storedState, storedUrl, rawUrl);
(this.events as Subject<Event>)
.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;