feat(router): allow passing `state` to routerLink directives (#27198)
This value will get written to the `history.state` entry. FW-613 (related) Related to #24617 PR Close #27198
This commit is contained in:
parent
67f4a5d4bd
commit
73f6ed9be1
|
@ -77,6 +77,27 @@ import {UrlTree} from '../url_tree';
|
|||
* </a>
|
||||
* ```
|
||||
*
|
||||
* You can provide a `state` value to be persisted to the browser's History.state
|
||||
* property (See https://developer.mozilla.org/en-US/docs/Web/API/History#Properties). It's
|
||||
* used as follows:
|
||||
*
|
||||
* ```
|
||||
* <a [routerLink]="['/user/bob']" [state]="{tracingId: 123}">
|
||||
* link to user component
|
||||
* </a>
|
||||
* ```
|
||||
*
|
||||
* And later the value can be read from the router through `router.getCurrentTransition.
|
||||
* For example, to capture the `tracingId` above during the `NavigationStart` event:
|
||||
*
|
||||
* ```
|
||||
* // Get NavigationStart events
|
||||
* router.events.pipe(filter(e => e instanceof NavigationStart)).subscribe(e => {
|
||||
* const transition = router.getCurrentTransition();
|
||||
* tracingService.trace({id: transition.extras.state});
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The router link directive always treats the provided input as a delta to the current url.
|
||||
*
|
||||
* For instance, if the current url is `/user/(box//aux:team)`.
|
||||
|
@ -104,6 +125,7 @@ export class RouterLink {
|
|||
@Input() skipLocationChange !: boolean;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@Input() replaceUrl !: boolean;
|
||||
@Input() state?: {[k: string]: any};
|
||||
private commands: any[] = [];
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private preserve !: boolean;
|
||||
|
@ -185,6 +207,7 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
|
|||
@Input() skipLocationChange !: boolean;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@Input() replaceUrl !: boolean;
|
||||
@Input() state?: {[k: string]: any};
|
||||
private commands: any[] = [];
|
||||
private subscription: Subscription;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
|
@ -237,6 +260,7 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
|
|||
const extras = {
|
||||
skipLocationChange: attrBoolValue(this.skipLocationChange),
|
||||
replaceUrl: attrBoolValue(this.replaceUrl),
|
||||
state: this.state
|
||||
};
|
||||
this.router.navigateByUrl(this.urlTree, extras);
|
||||
return false;
|
||||
|
|
|
@ -1878,6 +1878,36 @@ describe('Integration', () => {
|
|||
|
||||
expect(location.path()).toEqual('/team/22/simple?q=1#f');
|
||||
})));
|
||||
|
||||
it('should support history state',
|
||||
fakeAsync(inject([Router, Location], (router: Router, location: SpyLocation) => {
|
||||
const fixture = createRoot(router, RootCmp);
|
||||
|
||||
router.resetConfig([{
|
||||
path: 'team/:id',
|
||||
component: TeamCmp,
|
||||
children: [
|
||||
{path: 'link', component: LinkWithState},
|
||||
{path: 'simple', component: SimpleCmp}
|
||||
]
|
||||
}]);
|
||||
|
||||
router.navigateByUrl('/team/22/link');
|
||||
advance(fixture);
|
||||
|
||||
const native = fixture.nativeElement.querySelector('a');
|
||||
expect(native.getAttribute('href')).toEqual('/team/22/simple');
|
||||
native.click();
|
||||
advance(fixture);
|
||||
|
||||
expect(fixture.nativeElement).toHaveText('team 22 [ simple, right: ]');
|
||||
|
||||
// Check the history entry
|
||||
const history = (location as any)._history;
|
||||
|
||||
expect(history[history.length - 1].state.foo).toBe('bar');
|
||||
expect(history[history.length - 1].state).toEqual({foo: 'bar', navigationId: history.length});
|
||||
})));
|
||||
});
|
||||
|
||||
describe('redirects', () => {
|
||||
|
@ -4576,6 +4606,13 @@ class RelativeLinkCmp {
|
|||
class LinkWithQueryParamsAndFragment {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'link-cmp',
|
||||
template: `<a [routerLink]="['../simple']" [state]="{foo: 'bar'}">link</a>`
|
||||
})
|
||||
class LinkWithState {
|
||||
}
|
||||
|
||||
@Component({selector: 'simple-cmp', template: `simple`})
|
||||
class SimpleCmp {
|
||||
}
|
||||
|
@ -4770,6 +4807,7 @@ class LazyComponent {
|
|||
RelativeLinkCmp,
|
||||
DummyLinkWithParentCmp,
|
||||
LinkWithQueryParamsAndFragment,
|
||||
LinkWithState,
|
||||
CollectParamsCmp,
|
||||
QueryParamsAndFragmentCmp,
|
||||
StringLinkButtonCmp,
|
||||
|
@ -4797,6 +4835,7 @@ class LazyComponent {
|
|||
RelativeLinkCmp,
|
||||
DummyLinkWithParentCmp,
|
||||
LinkWithQueryParamsAndFragment,
|
||||
LinkWithState,
|
||||
CollectParamsCmp,
|
||||
QueryParamsAndFragmentCmp,
|
||||
StringLinkButtonCmp,
|
||||
|
@ -4826,6 +4865,7 @@ class LazyComponent {
|
|||
RelativeLinkCmp,
|
||||
DummyLinkWithParentCmp,
|
||||
LinkWithQueryParamsAndFragment,
|
||||
LinkWithState,
|
||||
CollectParamsCmp,
|
||||
QueryParamsAndFragmentCmp,
|
||||
StringLinkButtonCmp,
|
||||
|
|
Loading…
Reference in New Issue