fix(router): update current state and url before activating components
This commit is contained in:
@ -124,7 +124,6 @@ export class Router {
|
||||
private routerEvents: Subject<Event>;
|
||||
private navigationId: number = 0;
|
||||
private config: Routes;
|
||||
private futureUrlTree: UrlTree;
|
||||
private configLoader: RouterConfigLoader;
|
||||
|
||||
/**
|
||||
@ -138,7 +137,6 @@ export class Router {
|
||||
this.resetConfig(config);
|
||||
this.routerEvents = new Subject<Event>();
|
||||
this.currentUrlTree = createEmptyUrlTree();
|
||||
this.futureUrlTree = this.currentUrlTree;
|
||||
this.configLoader = new RouterConfigLoader(loader);
|
||||
this.currentRouterState = createEmptyState(this.currentUrlTree, this.rootComponentType);
|
||||
}
|
||||
@ -230,18 +228,6 @@ export class Router {
|
||||
return createUrlTree(a, this.currentUrlTree, commands, queryParams, fragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by RouterLinkWithHref to update HREFs.
|
||||
* We have to use the futureUrl because we run change detection ind the middle of activation when
|
||||
* the current url has not been updated yet.
|
||||
* @internal
|
||||
*/
|
||||
createUrlTreeUsingFutureUrl(
|
||||
commands: any[], {relativeTo, queryParams, fragment}: NavigationExtras = {}): UrlTree {
|
||||
const a = relativeTo ? relativeTo : this.routerState.root;
|
||||
return createUrlTree(a, this.futureUrlTree, commands, queryParams, fragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate based on the provided url. This navigation is always absolute.
|
||||
*
|
||||
@ -317,18 +303,22 @@ export class Router {
|
||||
let state: RouterState;
|
||||
let navigationIsSuccessful: boolean;
|
||||
let preActivation: PreActivation;
|
||||
|
||||
let appliedUrl: UrlTree;
|
||||
|
||||
const storedState = this.currentRouterState;
|
||||
const storedUrl = this.currentUrlTree;
|
||||
|
||||
applyRedirects(this.configLoader, url, this.config)
|
||||
.mergeMap(u => {
|
||||
this.futureUrlTree = u;
|
||||
appliedUrl = u;
|
||||
return recognize(
|
||||
this.rootComponentType, this.config, this.futureUrlTree,
|
||||
this.serializeUrl(this.futureUrlTree));
|
||||
this.rootComponentType, this.config, appliedUrl, this.serializeUrl(appliedUrl));
|
||||
})
|
||||
|
||||
.mergeMap((newRouterStateSnapshot) => {
|
||||
this.routerEvents.next(new RoutesRecognized(
|
||||
id, this.serializeUrl(url), this.serializeUrl(this.futureUrlTree),
|
||||
newRouterStateSnapshot));
|
||||
id, this.serializeUrl(url), this.serializeUrl(appliedUrl), newRouterStateSnapshot));
|
||||
return resolve(this.resolver, newRouterStateSnapshot);
|
||||
|
||||
})
|
||||
@ -361,12 +351,13 @@ export class Router {
|
||||
return;
|
||||
}
|
||||
|
||||
new ActivateRoutes(state, this.currentRouterState).activate(this.outletMap);
|
||||
|
||||
this.currentUrlTree = this.futureUrlTree;
|
||||
this.currentUrlTree = appliedUrl;
|
||||
this.currentRouterState = state;
|
||||
|
||||
new ActivateRoutes(state, storedState).activate(this.outletMap);
|
||||
|
||||
if (!preventPushState) {
|
||||
let path = this.urlSerializer.serialize(this.futureUrlTree);
|
||||
let path = this.urlSerializer.serialize(appliedUrl);
|
||||
if (this.location.isCurrentPathEqualTo(path)) {
|
||||
this.location.replaceState(path);
|
||||
} else {
|
||||
@ -377,11 +368,13 @@ export class Router {
|
||||
})
|
||||
.then(
|
||||
() => {
|
||||
this.routerEvents.next(new NavigationEnd(
|
||||
id, this.serializeUrl(url), this.serializeUrl(this.futureUrlTree)));
|
||||
this.routerEvents.next(
|
||||
new NavigationEnd(id, this.serializeUrl(url), this.serializeUrl(appliedUrl)));
|
||||
resolvePromise(navigationIsSuccessful);
|
||||
},
|
||||
e => {
|
||||
this.currentRouterState = storedState;
|
||||
this.currentUrlTree = storedUrl;
|
||||
this.routerEvents.next(new NavigationError(id, this.serializeUrl(url), e));
|
||||
rejectPromise(e);
|
||||
});
|
||||
|
Reference in New Issue
Block a user