fix(router): guards restor an incorrect url when used with skipLocationChange
Closes #12825
This commit is contained in:
parent
602522beb2
commit
ad20d7d260
|
@ -299,6 +299,7 @@ type NavigationParams = {
|
||||||
export class Router {
|
export class Router {
|
||||||
private currentUrlTree: UrlTree;
|
private currentUrlTree: UrlTree;
|
||||||
private rawUrlTree: UrlTree;
|
private rawUrlTree: UrlTree;
|
||||||
|
private currentUrlTreeStoredInLocation: UrlTree;
|
||||||
|
|
||||||
private navigations: BehaviorSubject<NavigationParams> =
|
private navigations: BehaviorSubject<NavigationParams> =
|
||||||
new BehaviorSubject<NavigationParams>(null);
|
new BehaviorSubject<NavigationParams>(null);
|
||||||
|
@ -716,6 +717,7 @@ export class Router {
|
||||||
let navigationIsSuccessful: boolean;
|
let navigationIsSuccessful: boolean;
|
||||||
const storedState = this.currentRouterState;
|
const storedState = this.currentRouterState;
|
||||||
const storedUrl = this.currentUrlTree;
|
const storedUrl = this.currentUrlTree;
|
||||||
|
const storedUrlInLocation = this.currentUrlTreeStoredInLocation;
|
||||||
|
|
||||||
routerState$
|
routerState$
|
||||||
.forEach(({appliedUrl, state, shouldActivate}: any) => {
|
.forEach(({appliedUrl, state, shouldActivate}: any) => {
|
||||||
|
@ -726,6 +728,8 @@ export class Router {
|
||||||
|
|
||||||
this.currentUrlTree = appliedUrl;
|
this.currentUrlTree = appliedUrl;
|
||||||
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
|
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
|
||||||
|
this.currentUrlTreeStoredInLocation =
|
||||||
|
shouldPreventPushState ? this.currentUrlTreeStoredInLocation : this.rawUrlTree;
|
||||||
|
|
||||||
this.currentRouterState = state;
|
this.currentRouterState = state;
|
||||||
|
|
||||||
|
@ -774,14 +778,13 @@ export class Router {
|
||||||
this.currentRouterState = storedState;
|
this.currentRouterState = storedState;
|
||||||
this.currentUrlTree = storedUrl;
|
this.currentUrlTree = storedUrl;
|
||||||
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
|
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
|
||||||
this.location.replaceState(this.serializeUrl(this.rawUrlTree));
|
this.location.replaceState(this.serializeUrl(storedUrlInLocation));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private resetUrlToCurrentUrlTree(): void {
|
private resetUrlToCurrentUrlTree(): void {
|
||||||
const path = this.urlSerializer.serialize(this.rawUrlTree);
|
this.location.replaceState(this.urlSerializer.serialize(this.currentUrlTreeStoredInLocation));
|
||||||
this.location.replaceState(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1532,6 +1532,27 @@ describe('Integration', () => {
|
||||||
expect(location.path()).toEqual('/main/component1');
|
expect(location.path()).toEqual('/main/component1');
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
it('should respect skipLocationChange when guards cancel navigations',
|
||||||
|
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
|
||||||
|
const fixture = createRoot(router, RootCmp);
|
||||||
|
|
||||||
|
router.resetConfig([
|
||||||
|
{path: 'component1', component: SimpleCmp},
|
||||||
|
{path: 'component2', component: SimpleCmp, canDeactivate: ['alwaysFalse']}
|
||||||
|
]);
|
||||||
|
|
||||||
|
router.navigateByUrl('/component1'); // initial state
|
||||||
|
advance(fixture);
|
||||||
|
|
||||||
|
router.navigateByUrl('/component2', {skipLocationChange: true});
|
||||||
|
advance(fixture);
|
||||||
|
expect(location.path()).toEqual('/component1');
|
||||||
|
|
||||||
|
location.back();
|
||||||
|
advance(fixture);
|
||||||
|
|
||||||
|
expect(location.path()).toEqual('/component1');
|
||||||
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should work when given a class', () => {
|
describe('should work when given a class', () => {
|
||||||
|
|
Loading…
Reference in New Issue