/** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import {LocationStrategy} from '@angular/common'; import {Directive, HostBinding, HostListener, Input, OnChanges, OnDestroy} from '@angular/core'; import {Subscription} from 'rxjs/Subscription'; 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. * * Consider the following route configuration: * ``` * [{ path: 'user/:name', component: UserCmp }] * ``` * * When linking to this `User` route, you can write: * * ``` * link to user component * ``` * * If you use dynamic values to generate the link, you can pass an array of path * segments, followed by the params for each segment. * * For instance `['/team', teamId, 'user', userName, {details: true}]` * means that we want to generate a link to `/team/11/user/bob;details=true`. * Multiple static segments can be merged into one (e.g., `['/team/11/user', userName, {details: true}]`). * * The first segment name can be prepended with `/`, `./`, or `../`: * * If the first segment begins with `/`, the router will look up the route from the root of the app. * * If the first segment begins with `./`, or doesn't begin with a slash, the router will * instead look in the children of the current activated route. * * And if the first segment begins with `../`, the router will go up one level. * * You can set query params and fragment as follows: * * ``` * link to user component * ``` * * RouterLink will use these to generate this link: `/user/bob#education?debug=true`. * * @stable */ @Directive({selector: ':not(a)[routerLink]'}) export class RouterLink { private commands: any[] = []; @Input() queryParams: {[k: string]: any}; @Input() fragment: string; urlTree: UrlTree; constructor( private router: Router, private route: ActivatedRoute, private locationStrategy: LocationStrategy) {} @Input() set routerLink(data: any[]|string) { if (Array.isArray(data)) { this.commands = data; } else { this.commands = [data]; } } @HostListener('click', ['$event.button', '$event.ctrlKey', '$event.metaKey']) onClick(button: number, ctrlKey: boolean, metaKey: boolean): boolean { if (button !== 0 || ctrlKey || metaKey) { return true; } this.urlTree = this.router.createUrlTreeUsingFutureUrl( this.commands, {relativeTo: this.route, queryParams: this.queryParams, fragment: this.fragment}); this.router.navigateByUrl(this.urlTree); return false; } } /** * See {@link RouterLink} for more information. * @stable */ @Directive({selector: 'a[routerLink]'}) 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; urlTree: UrlTree; /** * @internal */ constructor( private router: Router, private route: ActivatedRoute, private locationStrategy: LocationStrategy) { this.subscription = router.events.subscribe(s => { if (s instanceof NavigationEnd) { this.updateTargetUrlAndHref(); } }); } @Input() set routerLink(data: any[]|string) { if (Array.isArray(data)) { this.commands = data; } else { this.commands = [data]; } } 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 { if (button !== 0 || ctrlKey || metaKey) { return true; } if (typeof this.target === 'string' && this.target != '_self') { return true; } this.router.navigateByUrl(this.urlTree); return false; } private updateTargetUrlAndHref(): void { this.urlTree = this.router.createUrlTreeUsingFutureUrl( this.commands, {relativeTo: this.route, queryParams: this.queryParams, fragment: this.fragment}); if (this.urlTree) { this.href = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.urlTree)); } } }