通过编写添加新 class 的自定义指令更改 "router-link-active" class 的默认名称
Changing the default name of "router-link-active" class by writing a custom directive that adds new class
我想在我的 Angular2 应用程序中使用语义 UI。问题是我找不到更改 "router-link-active" class 默认名称的路由器设置。我只需要调用它 "active" 即可正确显示菜单。
据我了解,不存在这样的设置。我在 Vue.JS 中看到过它,所以我希望它也在那里。让开发人员解决这个问题是个好主意吗?
所以。我们需要编写一个自定义指令,将 "active" class 添加到所有具有 "router-link-active" class 的 DOM 元素,但我在这里也遇到了一些问题。
有一个 similar question,但答案太复杂,对我不起作用。所以我阅读了一些文档并决定像这样做一些更好的事情:
commons.ts:
@Directive({
selector: '.router-link-active',
host: {'[class.active]': 'trueConst'} //just 'true' could also work I think...
})
export class ActiveRouterLinkClass {
trueConst: boolean = true; //...if 'true' works we don't need this
}
然后我将 ActiveRouterLinkClass 导入我的 main.component.ts 并将其添加到组件的指令列表中。不幸的是,现在我有这个错误:"EXCEPTION: Unexpected directive value 'undefined' on the View of component 'Main'"。请解释我做错了什么!
Angular 不会将指令或组件应用于动态应用的选择器。如果 class .router-link-active
添加到 link 是动态的,因此将不起作用。
您可以做的是使用更通用的选择器,例如 [routerLink]
,而不是使用 @Input()
读取是否设置了 .router-link-active
,然后使用 class 设置所需的 class主机绑定。
@Directive({
selector: '[routerLink]')
export class RouterLinkReplaceClass {
// add class `my-active` when `myActiveClass` is `true`
@HostBinding('class.my-active')
// read `router-link-active` class state
@Input('class.router-link-active')
myActiveClass: bool = false;
}
另见 In Angular 2 how do I assign a custom class to an active router link?
更新
因为 myActiveClass
在 router-link-active
class 为 added/removed 时未更新 我修改了指令以获取有关活动路线的信息,方式与RouterLink
指令:
import {ROUTER_DIRECTIVES, RouteConfig, Router, Instruction} from 'angular2/router';
@Directive({
selector: '[routerLink]'
})
export class RouterLinkReplaceClass {
//@Input('class.router-link-active')
// myActiveClass: boolean = false;
private _navigationInstruction: Instruction;
@Input('routerLink')
private _routeParams: any[];
constructor(private _router: Router) {
// we need to update the link whenever a route changes to account for aux routes
this._router.subscribe((_) => this._updateLink());
}
private _updateLink(): void {
this._navigationInstruction = this._router.generate(this._routeParams);
}
@HostBinding('class.my-active')
get isRouteActive(): boolean {
return this._navigationInstruction ? this._router.isRouteActive(this._navigationInstruction) : null;
}
}
根据 Günter Zöchbauer 的回答,在打破了 angular2 rc1 中的更改后,这对我有用。
import { Directive, Input, HostBinding, OnInit } from '@angular/core';
import { Router, RouteSegment, UrlTree } from '@angular/router';
@Directive({
selector: '[routerLink]'
})
export class RouterActiveClass implements OnInit {
private currentUrl: UrlTree;
@Input('routerLink') private routerLink: any[];
constructor(private routeSegment: RouteSegment, private router: Router) {
this.router.changes.subscribe(() => this.updateCurrentUrl());
}
private updateCurrentUrl(): void {
this.currentUrl = this.router.createUrlTree(this.routerLink, this.routeSegment);
}
@HostBinding('class.active')
get isRouteActive(): boolean {
return this.currentUrl ? this.router.urlTree.contains(this.currentUrl) : null;
}
ngOnInit() {
this.updateCurrentUrl();
}
}
我想在我的 Angular2 应用程序中使用语义 UI。问题是我找不到更改 "router-link-active" class 默认名称的路由器设置。我只需要调用它 "active" 即可正确显示菜单。
据我了解,不存在这样的设置。我在 Vue.JS 中看到过它,所以我希望它也在那里。让开发人员解决这个问题是个好主意吗?
所以。我们需要编写一个自定义指令,将 "active" class 添加到所有具有 "router-link-active" class 的 DOM 元素,但我在这里也遇到了一些问题。
有一个 similar question,但答案太复杂,对我不起作用。所以我阅读了一些文档并决定像这样做一些更好的事情:
commons.ts:
@Directive({
selector: '.router-link-active',
host: {'[class.active]': 'trueConst'} //just 'true' could also work I think...
})
export class ActiveRouterLinkClass {
trueConst: boolean = true; //...if 'true' works we don't need this
}
然后我将 ActiveRouterLinkClass 导入我的 main.component.ts 并将其添加到组件的指令列表中。不幸的是,现在我有这个错误:"EXCEPTION: Unexpected directive value 'undefined' on the View of component 'Main'"。请解释我做错了什么!
Angular 不会将指令或组件应用于动态应用的选择器。如果 class .router-link-active
添加到 link 是动态的,因此将不起作用。
您可以做的是使用更通用的选择器,例如 [routerLink]
,而不是使用 @Input()
读取是否设置了 .router-link-active
,然后使用 class 设置所需的 class主机绑定。
@Directive({
selector: '[routerLink]')
export class RouterLinkReplaceClass {
// add class `my-active` when `myActiveClass` is `true`
@HostBinding('class.my-active')
// read `router-link-active` class state
@Input('class.router-link-active')
myActiveClass: bool = false;
}
另见 In Angular 2 how do I assign a custom class to an active router link?
更新
因为 myActiveClass
在 router-link-active
class 为 added/removed 时未更新 我修改了指令以获取有关活动路线的信息,方式与RouterLink
指令:
import {ROUTER_DIRECTIVES, RouteConfig, Router, Instruction} from 'angular2/router';
@Directive({
selector: '[routerLink]'
})
export class RouterLinkReplaceClass {
//@Input('class.router-link-active')
// myActiveClass: boolean = false;
private _navigationInstruction: Instruction;
@Input('routerLink')
private _routeParams: any[];
constructor(private _router: Router) {
// we need to update the link whenever a route changes to account for aux routes
this._router.subscribe((_) => this._updateLink());
}
private _updateLink(): void {
this._navigationInstruction = this._router.generate(this._routeParams);
}
@HostBinding('class.my-active')
get isRouteActive(): boolean {
return this._navigationInstruction ? this._router.isRouteActive(this._navigationInstruction) : null;
}
}
根据 Günter Zöchbauer 的回答,在打破了 angular2 rc1 中的更改后,这对我有用。
import { Directive, Input, HostBinding, OnInit } from '@angular/core';
import { Router, RouteSegment, UrlTree } from '@angular/router';
@Directive({
selector: '[routerLink]'
})
export class RouterActiveClass implements OnInit {
private currentUrl: UrlTree;
@Input('routerLink') private routerLink: any[];
constructor(private routeSegment: RouteSegment, private router: Router) {
this.router.changes.subscribe(() => this.updateCurrentUrl());
}
private updateCurrentUrl(): void {
this.currentUrl = this.router.createUrlTree(this.routerLink, this.routeSegment);
}
@HostBinding('class.active')
get isRouteActive(): boolean {
return this.currentUrl ? this.router.urlTree.contains(this.currentUrl) : null;
}
ngOnInit() {
this.updateCurrentUrl();
}
}