fix(router): fix skipLocationChanges on RouterLink directives
fixes #13156
This commit is contained in:
parent
804943c9b1
commit
f562cbf86c
|
@ -102,7 +102,8 @@ export class RouterLink {
|
||||||
|
|
||||||
@HostListener('click', [])
|
@HostListener('click', [])
|
||||||
onClick(): boolean {
|
onClick(): boolean {
|
||||||
this.router.navigateByUrl(this.urlTree);
|
const extras = {skipLocationChange: attrBoolValue(this.skipLocationChange)};
|
||||||
|
this.router.navigateByUrl(this.urlTree, extras);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,10 +112,9 @@ export class RouterLink {
|
||||||
relativeTo: this.route,
|
relativeTo: this.route,
|
||||||
queryParams: this.queryParams,
|
queryParams: this.queryParams,
|
||||||
fragment: this.fragment,
|
fragment: this.fragment,
|
||||||
preserveQueryParams: toBool(this.preserveQueryParams),
|
preserveQueryParams: attrBoolValue(this.preserveQueryParams),
|
||||||
preserveFragment: toBool(this.preserveFragment),
|
preserveFragment: attrBoolValue(this.preserveFragment),
|
||||||
skipLocationChange: toBool(this.skipLocationChange),
|
replaceUrl: attrBoolValue(this.replaceUrl),
|
||||||
replaceUrl: toBool(this.replaceUrl),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,8 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.router.navigateByUrl(this.urlTree);
|
const extras = {skipLocationChange: attrBoolValue(this.skipLocationChange)};
|
||||||
|
this.router.navigateByUrl(this.urlTree, extras);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,14 +190,13 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
|
||||||
relativeTo: this.route,
|
relativeTo: this.route,
|
||||||
queryParams: this.queryParams,
|
queryParams: this.queryParams,
|
||||||
fragment: this.fragment,
|
fragment: this.fragment,
|
||||||
preserveQueryParams: toBool(this.preserveQueryParams),
|
preserveQueryParams: attrBoolValue(this.preserveQueryParams),
|
||||||
preserveFragment: toBool(this.preserveFragment),
|
preserveFragment: attrBoolValue(this.preserveFragment),
|
||||||
skipLocationChange: toBool(this.skipLocationChange),
|
replaceUrl: attrBoolValue(this.replaceUrl),
|
||||||
replaceUrl: toBool(this.replaceUrl),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toBool(s: any): boolean {
|
function attrBoolValue(s: any): boolean {
|
||||||
return s === '' || !!s;
|
return s === '' || !!s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {CommonModule, Location} from '@angular/common';
|
import {CommonModule, Location} from '@angular/common';
|
||||||
import {Component, Injector, NgModule, NgModuleFactoryLoader} from '@angular/core';
|
import {Component, NgModule, NgModuleFactoryLoader} from '@angular/core';
|
||||||
import {ComponentFixture, TestBed, async, fakeAsync, inject, tick} from '@angular/core/testing';
|
import {ComponentFixture, TestBed, fakeAsync, inject, tick} from '@angular/core/testing';
|
||||||
|
import {By} from '@angular/platform-browser/src/dom/debug/by';
|
||||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
import {map} from 'rxjs/operator/map';
|
import {map} from 'rxjs/operator/map';
|
||||||
|
@ -18,7 +19,6 @@ import {RouterPreloader} from '../src/router_preloader';
|
||||||
import {forEach} from '../src/utils/collection';
|
import {forEach} from '../src/utils/collection';
|
||||||
import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing';
|
import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing';
|
||||||
|
|
||||||
|
|
||||||
describe('Integration', () => {
|
describe('Integration', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
|
@ -909,6 +909,37 @@ describe('Integration', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('router links', () => {
|
describe('router links', () => {
|
||||||
|
it('should support skipping location update for anchor router links',
|
||||||
|
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
|
||||||
|
const fixture = TestBed.createComponent(RootCmp);
|
||||||
|
advance(fixture);
|
||||||
|
|
||||||
|
router.resetConfig([{path: 'team/:id', component: TeamCmp}]);
|
||||||
|
|
||||||
|
router.navigateByUrl('/team/22');
|
||||||
|
advance(fixture);
|
||||||
|
expect(location.path()).toEqual('/team/22');
|
||||||
|
expect(fixture.nativeElement).toHaveText('team 22 [ , right: ]');
|
||||||
|
|
||||||
|
const teamCmp = fixture.debugElement.childNodes[1].componentInstance;
|
||||||
|
|
||||||
|
teamCmp.routerLink = ['/team/0'];
|
||||||
|
advance(fixture);
|
||||||
|
const anchor = fixture.debugElement.query(By.css('a')).nativeElement;
|
||||||
|
anchor.click();
|
||||||
|
advance(fixture);
|
||||||
|
expect(fixture.nativeElement).toHaveText('team 0 [ , right: ]');
|
||||||
|
expect(location.path()).toEqual('/team/22');
|
||||||
|
|
||||||
|
teamCmp.routerLink = ['/team/1'];
|
||||||
|
advance(fixture);
|
||||||
|
const button = fixture.debugElement.query(By.css('button')).nativeElement;
|
||||||
|
button.click();
|
||||||
|
advance(fixture);
|
||||||
|
expect(fixture.nativeElement).toHaveText('team 1 [ , right: ]');
|
||||||
|
expect(location.path()).toEqual('/team/22');
|
||||||
|
})));
|
||||||
|
|
||||||
it('should support string router links', fakeAsync(inject([Router], (router: Router) => {
|
it('should support string router links', fakeAsync(inject([Router], (router: Router) => {
|
||||||
const fixture = createRoot(router, RootCmp);
|
const fixture = createRoot(router, RootCmp);
|
||||||
|
|
||||||
|
@ -2591,12 +2622,15 @@ class BlankCmp {
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'team-cmp',
|
selector: 'team-cmp',
|
||||||
template:
|
template: `team {{id | async}} ` +
|
||||||
`team {{id | async}} [ <router-outlet></router-outlet>, right: <router-outlet name="right"></router-outlet> ]`
|
`[ <router-outlet></router-outlet>, right: <router-outlet name="right"></router-outlet> ]` +
|
||||||
|
`<a [routerLink]="routerLink" skipLocationChange></a>` +
|
||||||
|
`<button [routerLink]="routerLink" skipLocationChange></button>`
|
||||||
})
|
})
|
||||||
class TeamCmp {
|
class TeamCmp {
|
||||||
id: Observable<string>;
|
id: Observable<string>;
|
||||||
recordedParams: Params[] = [];
|
recordedParams: Params[] = [];
|
||||||
|
routerLink = ['.'];
|
||||||
|
|
||||||
constructor(public route: ActivatedRoute) {
|
constructor(public route: ActivatedRoute) {
|
||||||
this.id = map.call(route.params, (p: any) => p['id']);
|
this.id = map.call(route.params, (p: any) => p['id']);
|
||||||
|
|
Loading…
Reference in New Issue