fix(router): restore 'history.state' object for navigations coming from Angular router (#28108) (#28176)
When navigations coming from Angular router we may have a payload stored in state property. When this exists, set extras's state to the payload. PR Close #28176
This commit is contained in:
parent
3d156162af
commit
df76a2048b
|
@ -920,7 +920,15 @@ export class Router {
|
|||
// hybrid apps.
|
||||
setTimeout(() => {
|
||||
const {source, state, urlTree} = currentChange;
|
||||
this.scheduleNavigation(urlTree, source, state, {replaceUrl: true});
|
||||
const extras: NavigationExtras = {replaceUrl: true};
|
||||
if (state) {
|
||||
const stateCopy = {...state};
|
||||
delete stateCopy.navigationId;
|
||||
if (Object.keys(stateCopy).length !== 0) {
|
||||
extras.state = stateCopy;
|
||||
}
|
||||
}
|
||||
this.scheduleNavigation(urlTree, source, state, extras);
|
||||
}, 0);
|
||||
}
|
||||
this.lastLocationChangeInfo = currentChange;
|
||||
|
|
|
@ -159,6 +159,59 @@ describe('Integration', () => {
|
|||
expect(navigation.extras.state).toEqual({foo: 'bar'});
|
||||
})));
|
||||
|
||||
it('should set history.state when navigation with browser back and forward',
|
||||
fakeAsync(inject([Router, Location], (router: Router, location: SpyLocation) => {
|
||||
router.resetConfig([
|
||||
{path: '', component: SimpleCmp},
|
||||
{path: 'simple', component: SimpleCmp},
|
||||
]);
|
||||
|
||||
const fixture = createRoot(router, RootCmp);
|
||||
let navigation: Navigation = null!;
|
||||
router.events.subscribe(e => {
|
||||
if (e instanceof NavigationStart) {
|
||||
navigation = <Navigation>router.getCurrentNavigation()!;
|
||||
}
|
||||
});
|
||||
|
||||
const state = {foo: 'bar'};
|
||||
router.navigateByUrl('/simple', {state});
|
||||
tick();
|
||||
location.back();
|
||||
tick();
|
||||
location.forward();
|
||||
tick();
|
||||
|
||||
expect(navigation.extras.state).toBeDefined();
|
||||
expect(navigation.extras.state).toEqual(state);
|
||||
})));
|
||||
|
||||
it('should not error if state is not {[key: string]: any}',
|
||||
fakeAsync(inject([Router, Location], (router: Router, location: SpyLocation) => {
|
||||
router.resetConfig([
|
||||
{path: '', component: SimpleCmp},
|
||||
{path: 'simple', component: SimpleCmp},
|
||||
]);
|
||||
|
||||
const fixture = createRoot(router, RootCmp);
|
||||
let navigation: Navigation = null!;
|
||||
router.events.subscribe(e => {
|
||||
if (e instanceof NavigationStart) {
|
||||
navigation = <Navigation>router.getCurrentNavigation()!;
|
||||
}
|
||||
});
|
||||
|
||||
location.replaceState('', '', 42);
|
||||
router.navigateByUrl('/simple');
|
||||
tick();
|
||||
location.back();
|
||||
advance(fixture);
|
||||
|
||||
// Angular does not support restoring state to the primitive.
|
||||
expect(navigation.extras.state).toEqual(undefined);
|
||||
expect(location.getState()).toEqual({navigationId: 3});
|
||||
})));
|
||||
|
||||
it('should not pollute browser history when replaceUrl is set to true',
|
||||
fakeAsync(inject([Router, Location], (router: Router, location: SpyLocation) => {
|
||||
router.resetConfig([
|
||||
|
|
Loading…
Reference in New Issue