Angular 4.x Router Link Directives
RouterLink 指令简介RouterLink 指令可以让你链接到应用程序的特定部分。若链接是静态的,我们可以按照以下的方式,来使用该指令: <a routerLink="/user/bob">link to user component</a> 如果你需要使用动态值生成链接地址,你可以传递一个路径片段 (segments) 的数组,然后再传递每个段的参数。例如使用 多个静态段 (segments) 能够被合并为一个,例如 第一个路径片段可以以
你可以使用以下方式设置查询参数和片段 (fragment): <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education"> link to user component </a> RouterLink 指令将基于以上设定的输入参数,生成如下链接:
具体使用示例如下: <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge"> link to user component </a> RouterLink 指令详解RouterLink 指令定义@Directive({selector: ':not(a)[routerLink]'}) RouterLink 指令输入属性// 设置URL相关的查询参数 @Input() queryParams: {[k: string]: any}; // 设置URL上的hash fragment @Input() fragment: string; // 设置查询参数处理方式:merge、preserve 、default @Input() queryParamsHandling: QueryParamsHandling; // 设置是否保留fragment @Input() preserveFragment: boolean; // 设置页面导航时,是否把新的状态添加到历史记录中 @Input() skipLocationChange: boolean; // 设置页面导航的同时,是否替换历史记录中的当前状态 @Input() replaceUrl: boolean; // 设置commands参数信息,如:['/user/bob'] @Input() set routerLink(commands: any[]|string) { if (commands != null) { this.commands = Array.isArray(commands) ? commands : [commands]; } else { this.commands = []; } } RouterLink 指令绑定事件绑定// 监听RouterLink指令宿主元素的click事件,进行页面切换 @HostListener('click') onClick(): boolean { const extras = { skipLocationChange: attrBoolValue(this.skipLocationChange),replaceUrl: attrBoolValue(this.replaceUrl),}; this.router.navigateByUrl(this.urlTree,extras); return true; } // 转化设置的属性值为bool值 function attrBoolValue(s: any): boolean { return s === '' || !!s; } RouterLink 类的构造函数export class RouterLink { constructor( private router: Router,private route: ActivatedRoute,@Attribute('tabindex') tabIndex: string,renderer: Renderer,el: ElementRef) { if (tabIndex == null) { renderer.setElementAttribute(el.nativeElement,'tabindex','0'); } } } @Attribute()@Attribute('attributeName') 装饰器:用于获取指令宿主元素上 tabindextabindex 属性规定元素的 tab 键控制次序 (当 tab 键用于导航时)。 以下元素支持 tabindex 属性: tabindex 语法: <element tabindex="number"> <!-- number:规定元素的 tab 键控制次序 (1是第一个)--> RouterLink 类的属性// 用于保存commands参数信息 private commands: any[] = []; // 标识是否保存查询参数,4.0.0版本后用queryParamsHandling代替 private preserve: boolean; RouterLink 类的方法// 获取routerLink上配置信息对应的UrlTree get urlTree(): UrlTree { return this.router.createUrlTree(this.commands,{ relativeTo: this.route,queryParams: this.queryParams,fragment: this.fragment,preserveQueryParams: attrBoolValue(this.preserve),queryParamsHandling: this.queryParamsHandling,preserveFragment: attrBoolValue(this.preserveFragment),}); } // angularpackagesroutersrcrouter.ts // 创建UrlTree createUrlTree( commands: any[],{relativeTo,queryParams,fragment,preserveQueryParams,queryParamsHandling,preserveFragment}: NavigationExtras = {}): UrlTree { if (isDevMode() && preserveQueryParams && <any>console && <any>console.warn) { console.warn('preserveQueryParams is deprecated,use queryParamsHandling instead.'); } const a = relativeTo || this.routerState.root; const f = preserveFragment ? this.currentUrlTree.fragment : fragment; let q: Params|null = null; // 根据queryParamsHandling属性值,处理查询参数 if (queryParamsHandling) { switch (queryParamsHandling) { case 'merge': q = {...this.currentUrlTree.queryParams,...queryParams}; break; case 'preserve': q = this.currentUrlTree.queryParams; break; default: q = queryParams || null; } } else { q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams || null; } return createUrlTree(a,this.currentUrlTree,commands,q !,f !); } RouterLinkWithHref 指令详解RouterLinkWithHref 指令定义@Directive({selector: 'a[routerLink]'}) RouterLinkWithHref 指令输入属性// 设置a标签target的值 @Input() target: string; // 设置URL相关的查询参数 @Input() queryParams: {[k: string]: any}; // 设置URL上的hash fragment @Input() fragment: string; // 设置查询参数处理方式:merge、preserve 、default @Input() queryParamsHandling: QueryParamsHandling; // 设置是否保留fragment @Input() preserveFragment: boolean; // 设置页面导航时,是否把新的状态添加到历史记录中 @Input() skipLocationChange: boolean; // 设置页面导航的同时,是否替换历史记录中的当前状态 @Input() replaceUrl: boolean; // 设置commands信息,如:['/user/bob'] @Input() set routerLink(commands: any[]|string) { if (commands != null) { this.commands = Array.isArray(commands) ? commands : [commands]; } else { this.commands = []; } } RouterLinkWithHref 指令绑定属性绑定@HostBinding('attr.target') @Input() target: string; @HostBinding() href: string;
事件绑定// 监听RouterLink指令宿主元素的click事件,进行页面切换 @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; } const extras = { skipLocationChange: attrBoolValue(this.skipLocationChange),}; this.router.navigateByUrl(this.urlTree,extras); return false; } MouseEvent 表示用户与指针设备 (如鼠标) 交互时发生的事件,常见的事件包括:click、dblclick、mouseup 与 mousedown 事件。其中 MouseEvent 对象中包含一个
对于配置为左手使用的鼠标,按键操作将正好相反。此种情况下,从右至左读取值。在上面示例代码中,我们还访问了
若按下 RouterLinkWithHref 指令生命周期ngOnChanges()// 输入属性发生变化时,更新a标签href属性 ngOnChanges(changes: {}): any { this.updateTargetUrlAndHref(); } ngOnDestroy()// 指令销毁时,取消路由事件的订阅 ngOnDestroy(): any { this.subscription.unsubscribe(); } RouterLinkWithHref 类的构造函数export class RouterLinkWithHref implements OnChanges,OnDestroy { constructor( private router: Router,private locationStrategy: LocationStrategy) { // 订阅路由事件,当页面切换成功后更新a标签的href属性 this.subscription = router.events.subscribe(s => { if (s instanceof NavigationEnd) { this.updateTargetUrlAndHref(); } }); } } RouterLinkWithHref 类的属性// 用于保存commands参数信息 private commands: any[] = []; // 用于保存取消订阅路由事件订阅的Subscription对象 private subscription: Subscription; // 标识是否保存查询参数,4.0.0版本后用queryParamsHandling代替 private preserve: boolean; RouterLinkWithHref 类的方法// 获取routerLink上配置信息对应的UrlTree get urlTree(): UrlTree { return this.router.createUrlTree(this.commands,}); } // 更新a标签href属性值 private updateTargetUrlAndHref(): void { this.href = this.locationStrategy .prepareExternalUrl(this.router.serializeUrl(this.urlTree)); } RouterLinkActive 指令简介RouterLinkActive 指令允许你在链接的路由变为活动状态时向元素添加 CSS 类。请看一下以下示例: <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a> 当 URL 地址是 <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a> <a routerLink="/user/bob" [routerLinkActive]="['class1','class2']">Bob</a> 在应用 <a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">Bob</a> 当配置了 <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive"> Bob {{ rla.isActive ? '(already open)' : ''}} </a> 最后,你也可以将 RouterLinkActive 指令应用于 RouterLink 的父级元素。具体示例如下: <div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}"> <a routerLink="/user/jim">Jim</a> <a routerLink="/user/bob">Bob</a> </div> 在上面示例中,当 URL 的地址为 RouterLinkActive 指令详解RouterLinkActive 指令定义@Directive({ selector: '[routerLinkActive]',exportAs: 'routerLinkActive',}) RouterLinkActive 指令输入属性// 设置处于激活状态时,宿主元素上应用的class信息 @Input() set routerLinkActive(data: string[]|string) { const classes = Array.isArray(data) ? data : data.split(' '); this.classes = classes.filter(c => !!c); } // 设置URL地址的匹配方式 @Input() routerLinkActiveOptions: {exact: boolean} = {exact: false}; RouterLinkActive 指令生命周期ngAfterContentInit()// 订阅RouterLink或RouterLinkWithHref集合的changes对象,从而自动更新宿主元素的class信息 ngAfterContentInit(): void { this.links.changes.subscribe(_ => this.update()); this.linksWithHrefs.changes.subscribe(_ => this.update()); this.update(); } ngOnChanges()// 输入属性变化时,更新宿主元素的class信息 ngOnChanges(changes: SimpleChanges): void { this.update(); } ngOnDestroy()// 指令销毁时,取消路由事件的订阅 ngOnDestroy(): void { this.subscription.unsubscribe(); } RouterLinkActive 类的构造函数export class RouterLinkActive implements OnChanges,OnDestroy,AfterContentInit { constructor( private router: Router,private element: ElementRef,private renderer: Renderer,private cdr: ChangeDetectorRef) { // 订阅路由事件,当页面切换成功后更新宿主元素上的class信息 this.subscription = router.events.subscribe(s => { if (s instanceof NavigationEnd) { this.update(); } }); } } RouterLinkActive 类的属性// 获取RouterLink集合 @ContentChildren(RouterLink,{descendants: true}) links: QueryList<RouterLink>; // 获取RouterLinkWithHref集合 @ContentChildren(RouterLinkWithHref,{descendants: true}) linksWithHrefs: QueryList<RouterLinkWithHref>; // 激活状态的样式列表 private classes: string[] = []; // 用于保存取消订阅路由事件订阅的Subscription对象 private subscription: Subscription; // 标识是否处于激活状态 private active: boolean = false; RouterLinkActive 类的方法// 获取激活状态 get isActive(): boolean { return this.active; } // 更新宿主元素的class信息 private update(): void { if (!this.links || !this.linksWithHrefs || !this.router.navigated) return; const hasActiveLinks = this.hasActiveLinks(); // react only when status has changed to prevent unnecessary dom updates if (this.active !== hasActiveLinks) { this.classes.forEach( c => this.renderer.setElementClass(this.element.nativeElement,c,hasActiveLinks)); Promise.resolve(hasActiveLinks).then(active => this.active = active); } } // 判断是否是激活的链接 private isLinkActive(router: Router): (link: (RouterLink|RouterLinkWithHref)) => boolean { return (link: RouterLink | RouterLinkWithHref) => router.isActive(link.urlTree,this.routerLinkActiveOptions.exact); } // 判断RouterLink或RouterLinkWithHref集合中是否含有激活的链接 private hasActiveLinks(): boolean { return this.links.some(this.isLinkActive(this.router)) || this.linksWithHrefs.some(this.isLinkActive(this.router)); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |