diff --git a/modules/@angular/router/src/directives/router_link.ts b/modules/@angular/router/src/directives/router_link.ts
index e4d0cff442..f0f6db524b 100644
--- a/modules/@angular/router/src/directives/router_link.ts
+++ b/modules/@angular/router/src/directives/router_link.ts
@@ -7,12 +7,14 @@
*/
import {LocationStrategy} from '@angular/common';
-import {Directive, HostBinding, HostListener, Input, OnChanges} from '@angular/core';
+import {Directive, HostBinding, HostListener, Input, OnChanges, OnDestroy} from '@angular/core';
+import {Subscription} from 'rxjs/Subscription';
-import {Router} from '../router';
+import {NavigationEnd, Router} from '../router';
import {ActivatedRoute} from '../router_state';
import {UrlTree} from '../url_tree';
+
/**
* The RouterLink directive lets you link to specific parts of your app.
*
@@ -93,11 +95,12 @@ export class RouterLink {
* @stable
*/
@Directive({selector: 'a[routerLink]'})
-export class RouterLinkWithHref implements OnChanges {
+export class RouterLinkWithHref implements OnChanges, OnDestroy {
@Input() target: string;
private commands: any[] = [];
@Input() queryParams: {[k: string]: any};
@Input() fragment: string;
+ private subscription: Subscription;
// the url displayed on the anchor element.
@HostBinding() href: string;
@@ -109,7 +112,13 @@ export class RouterLinkWithHref implements OnChanges {
*/
constructor(
private router: Router, private route: ActivatedRoute,
- private locationStrategy: LocationStrategy) {}
+ private locationStrategy: LocationStrategy) {
+ this.subscription = router.events.subscribe(s => {
+ if (s instanceof NavigationEnd) {
+ this.updateTargetUrlAndHref();
+ }
+ });
+ }
@Input()
set routerLink(data: any[]|string) {
@@ -121,6 +130,7 @@ export class RouterLinkWithHref implements OnChanges {
}
ngOnChanges(changes: {}): any { this.updateTargetUrlAndHref(); }
+ ngOnDestroy(): any { this.subscription.unsubscribe(); }
@HostListener('click', ['$event.button', '$event.ctrlKey', '$event.metaKey'])
onClick(button: number, ctrlKey: boolean, metaKey: boolean): boolean {
diff --git a/modules/@angular/router/test/router.spec.ts b/modules/@angular/router/test/router.spec.ts
index d7b29f196c..78ba3c9a01 100644
--- a/modules/@angular/router/test/router.spec.ts
+++ b/modules/@angular/router/test/router.spec.ts
@@ -503,6 +503,33 @@ describe('Integration', () => {
expect(fixture.debugElement.nativeElement).toHaveText('team 33 { simple, right: }');
})));
+ it('should update hrefs when query params change',
+ fakeAsync(
+ inject([Router, TestComponentBuilder], (router: Router, tcb: TestComponentBuilder) => {
+
+ @Component({
+ selector: 'someRoot',
+ template: `Link`,
+ directives: ROUTER_DIRECTIVES
+ })
+ class RootCmpWithLink {
+ }
+
+ const fixture = createRoot(tcb, router, RootCmpWithLink);
+
+ router.resetConfig([{path: 'home', component: SimpleCmp}]);
+
+ const native = fixture.debugElement.nativeElement.querySelector('a');
+
+ router.navigateByUrl('/home?q=123');
+ advance(fixture);
+ expect(native.getAttribute('href')).toEqual('/home?q=123');
+
+ router.navigateByUrl('/home?q=456');
+ advance(fixture);
+ expect(native.getAttribute('href')).toEqual('/home?q=456');
+ })));
+
it('should support using links on non-a tags',
fakeAsync(
inject([Router, TestComponentBuilder], (router: Router, tcb: TestComponentBuilder) => {
@@ -1154,6 +1181,14 @@ class UserCmp {
}
}
+@Component({
+ selector: 'wrapper',
+ template: ``,
+ directives: [ROUTER_DIRECTIVES]
+})
+class WrapperCmp {
+}
+
@Component({
selector: 'query-cmp',
template: `query: {{name | async}} fragment: {{fragment | async}}`,
@@ -1192,7 +1227,7 @@ class RelativeLinkInIfCmp {
precompile: [
BlankCmp, SimpleCmp, TeamCmp, UserCmp, StringLinkCmp, DummyLinkCmp, AbsoluteLinkCmp,
RelativeLinkCmp, DummyLinkWithParentCmp, LinkWithQueryParamsAndFragment, CollectParamsCmp,
- QueryParamsAndFragmentCmp, StringLinkButtonCmp
+ QueryParamsAndFragmentCmp, StringLinkButtonCmp, WrapperCmp
]
})
class RootCmp {