diff --git a/modules/@angular/router/src/directives/router_link.ts b/modules/@angular/router/src/directives/router_link.ts
index e8bca982a1..28f2bba0bf 100644
--- a/modules/@angular/router/src/directives/router_link.ts
+++ b/modules/@angular/router/src/directives/router_link.ts
@@ -102,7 +102,8 @@ export class RouterLink {
@HostListener('click', [])
onClick(): boolean {
- this.router.navigateByUrl(this.urlTree);
+ const extras = {skipLocationChange: attrBoolValue(this.skipLocationChange)};
+ this.router.navigateByUrl(this.urlTree, extras);
return true;
}
@@ -111,10 +112,9 @@ export class RouterLink {
relativeTo: this.route,
queryParams: this.queryParams,
fragment: this.fragment,
- preserveQueryParams: toBool(this.preserveQueryParams),
- preserveFragment: toBool(this.preserveFragment),
- skipLocationChange: toBool(this.skipLocationChange),
- replaceUrl: toBool(this.replaceUrl),
+ preserveQueryParams: attrBoolValue(this.preserveQueryParams),
+ preserveFragment: attrBoolValue(this.preserveFragment),
+ replaceUrl: attrBoolValue(this.replaceUrl),
});
}
}
@@ -176,7 +176,8 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
return true;
}
- this.router.navigateByUrl(this.urlTree);
+ const extras = {skipLocationChange: attrBoolValue(this.skipLocationChange)};
+ this.router.navigateByUrl(this.urlTree, extras);
return false;
}
@@ -189,14 +190,13 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
relativeTo: this.route,
queryParams: this.queryParams,
fragment: this.fragment,
- preserveQueryParams: toBool(this.preserveQueryParams),
- preserveFragment: toBool(this.preserveFragment),
- skipLocationChange: toBool(this.skipLocationChange),
- replaceUrl: toBool(this.replaceUrl),
+ preserveQueryParams: attrBoolValue(this.preserveQueryParams),
+ preserveFragment: attrBoolValue(this.preserveFragment),
+ replaceUrl: attrBoolValue(this.replaceUrl),
});
}
}
-function toBool(s: any): boolean {
+function attrBoolValue(s: any): boolean {
return s === '' || !!s;
}
diff --git a/modules/@angular/router/test/integration.spec.ts b/modules/@angular/router/test/integration.spec.ts
index d4013eb6e5..0fb2a569fc 100644
--- a/modules/@angular/router/test/integration.spec.ts
+++ b/modules/@angular/router/test/integration.spec.ts
@@ -7,8 +7,9 @@
*/
import {CommonModule, Location} from '@angular/common';
-import {Component, Injector, NgModule, NgModuleFactoryLoader} from '@angular/core';
-import {ComponentFixture, TestBed, async, fakeAsync, inject, tick} from '@angular/core/testing';
+import {Component, NgModule, NgModuleFactoryLoader} from '@angular/core';
+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 {Observable} from 'rxjs/Observable';
import {map} from 'rxjs/operator/map';
@@ -18,7 +19,6 @@ import {RouterPreloader} from '../src/router_preloader';
import {forEach} from '../src/utils/collection';
import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing';
-
describe('Integration', () => {
beforeEach(() => {
TestBed.configureTestingModule({
@@ -909,6 +909,37 @@ describe('Integration', () => {
});
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) => {
const fixture = createRoot(router, RootCmp);
@@ -2591,12 +2622,15 @@ class BlankCmp {
@Component({
selector: 'team-cmp',
- template:
- `team {{id | async}} [ , right: ]`
+ template: `team {{id | async}} ` +
+ `[ , right: ]` +
+ `` +
+ ``
})
class TeamCmp {
id: Observable;
recordedParams: Params[] = [];
+ routerLink = ['.'];
constructor(public route: ActivatedRoute) {
this.id = map.call(route.params, (p: any) => p['id']);