通过编写添加新类的自定义指令来更改“router-link-active”类的默认名称

Posted

技术标签:

【中文标题】通过编写添加新类的自定义指令来更改“router-link-active”类的默认名称【英文标题】:Changing the default name of "router-link-active" class by writing a custom directive that adds new class 【发布时间】:2016-07-31 23:26:26 【问题描述】:

我想在我的 Angular2 应用程序中使用语义 UI。问题是我找不到更改“router-link-active”类的默认名称的路由器设置。我需要将其称为“活动”以使菜单正确显示。

据我了解,这样的设置不存在。我在 Vue.JS 中看到过它,所以我希望它也存在。要求开发人员解决这个问题是个好主意吗?

所以。我们需要编写一个自定义指令,将“active”类添加到所有具有“router-link-active”类的 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 导入到我的 ma​​in.component.ts 中,并将其添加到组件的指令列表中。不幸的是,现在我有这个错误:“异常:组件'Main'视图上的意外指令值'undefined'”。请解释一下我做错了什么!

【问题讨论】:

【参考方案1】:

根据 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();
    

【讨论】:

【参考方案2】:

Angular 不会将指令或组件应用于动态应用的选择器。如果类 .router-link-active 添加到链接是动态的,因此将不起作用。

您可以做的是使用更通用的选择器,例如 [routerLink],而不是读取是否使用 .router-link-active 设置了 @Input() 并使用主机绑定设置所需的类。

@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;

Plunker example

另见In Angular 2 how do I assign a custom class to an active router link?

更新

因为在添加/删除router-link-active 类时myActiveClass 没有更新,所以我修改了指令以与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;
  

【讨论】:

感谢您这么快的回答!但是您的示例看起来有点人为,因为您手动设置了“router-link-active”。我已经对其进行了编辑以显示我想要得到的内容:plnkr.co/edit/UU0mFn?p=preview 我希望当前的活动链接同时具有黄色背景和红色边框,但又出现了问题。有可能吗? 我尽量保持简单。感谢您的 Plunker 链接。当路由器设置类时,@Input() 没有更新,这很奇怪。对我来说似乎是一个错误。我还在调查。 我不敢相信更改班级名称会如此困难...干得好!但是还有更多……我有一个路由器插座在另一个插座(plnkr.co/edit/pEAWUP?p=preview)。我试图在 Some 的指令数组中留下或删除 RouterLinkReplaceClass,但它没有帮助。请再看一遍好吗? @GünterZöchbauer 我添加了更新的答案以使用 rc1。当你更新你的时,我会删除它,因为学分归你所有。 不用担心。感谢您的提示。无需删除。

以上是关于通过编写添加新类的自定义指令来更改“router-link-active”类的默认名称的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C编程 — 类和继承

更改类不会导致在 IE6 中应用新类的规则?

在不创建新类的情况下访问自定义 UITableViewCell 中的 UITextField?

为啥自定义指令不能立即反映其代码的变化

vuejs中类似于v-if的自定义指令

nuxt js中的自定义指令