更改" router-link-active"的默认名称class通过编写添加新类

时间:2016-04-11 00:03:47

标签: typescript angular router directive

我想在Angular2应用程序中使用Semantic 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导入我的 main.component.ts 并将其添加到组件的指令列表中。不幸的是,现在我有这样的错误:" EXCEPTION:意外的指令值' undefined'在组件的视图' Main'" 。请解释我做错了什么!

2 个答案:

答案 0 :(得分:4)

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?

<强>更新

因为在添加/删除myActiveClass类时未更新router-link-active我修改了指令以获取有关活动路由的信息,方法与RouterLink指令相同:< / p>

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

答案 1 :(得分:2)

根据GünterZö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();
    }
}