Angular 2确切的RouterLinkActive包括片段?

时间:2016-12-30 09:01:22

标签: angular angular2-routing

使用routerLinkrouterLinkActive将CSS应用于导航栏时,我还想包含fragment信息,以便链接对于主页中的部分是唯一的

我尝试使用[routerLinkActiveOptions]="{ exact: true }"没有运气。

导航条形码的相关部分是:

  <li routerLinkActive="active"
      [routerLinkActiveOptions]="{ exact: true }">
    <a routerLink="/sitio" fragment="inicio">Inicio</a>
  </li>
  <li routerLinkActive="active"
      [routerLinkActiveOptions]="{ exact: true }">
    <a routerLink="/sitio" fragment="invierte">Invierte</a>
  </li>
  <li routerLinkActive="active"
      [routerLinkActiveOptions]="{ exact: true }">
    <a routerLink="/sitio" fragment="contacto">Contacto</a>
  </li>

上述代码访问的三个不同的网址是:

  • /sitio#inicio
  • /sitio#invierte
  • /sitio#contacto

但是当点击其中任何一个时,所有这些都被标记为处于活动状态(因为它们对应于routerLink="/sitio"并且fragment=*信息未包含在检查中。这导致导航栏点击其中任何一个时看起来像这样:

enter image description here

关于如何做到这一点的任何想法?

5 个答案:

答案 0 :(得分:6)

我只是想如果有人遇到同样的问题我会解决它的问题:跟踪网站中的当前部分并通过组件中的函数使用类绑定而不是使用routerLinkActive

模板中的链接变为:

<li [class.active]="isSectionActive('inicio')">
    <a routerLink="/sitio" fragment="inicio">Inicio</a>
</li>
<li [class.active]="isSectionActive('invierte')">
    <a routerLink="/sitio" fragment="invierte">Invierte</a>
</li>
<li [class.active]="isSectionActive('contacto')">
    <a routerLink="/sitio" fragment="contacto">Contacto</a>
</li>

请注意,routerLinkActive没有使用,而是使用类绑定[class.active]=isSectionActive('<name-of-section>')

跟踪我们所在部分并决定是否在模板中应用CSS类的代码是:

import { Router, NavigationEnd } from '@angular/router';

// Class signature... {

    private activeSiteSection: string;

    constructor(
        private router: Router,
        private sessionService: SessionService
    ) {
        router.events.subscribe((event) => {
            if(event instanceof NavigationEnd ) {
                this.SiteURLActiveCheck(event);
            }
        });
    }

    private SiteURLActiveCheck(event: NavigationEnd): void {
        if (event.url.indexOf('#inicio') !== -1) {
            this.activeSiteSection = 'inicio';
        } else if (event.url.indexOf('#invierte') !== -1) {
            this.activeSiteSection = 'invierte';
        } else if (event.url.indexOf('#contacto') !== -1) {
            this.activeSiteSection = 'contacto';
        } else {
            this.activeSiteSection = '';
        }
    }

    private isSectionActive(section: string): boolean {
        return section === this.activeSiteSection;
    }
}

可能有点矫枉过正,但我​​宁愿选择这条路线而不是修改Angular 2的来源。 :)

答案 1 :(得分:4)

有一个未解决的问题需要支持https://github.com/angular/angular/issues/13205

routerLinkActive是一个简单的指令。您可以使用该扩展功能自行创建克隆。

答案 2 :(得分:0)

让Omar Trejo的方法更简单。我没有订阅Route,而是更新了isSectionActive以查看location.href以使其正常工作。

private isSectionActive(section: string): boolean {
    return location.href.indexOf(section) !== -1;
}

答案 3 :(得分:0)

即使在Angular 7上,我也很难与[routerLinkActiveOptions]="{ exact: true }"合作。

因此,我使用以下技巧来解决此问题。答案是ActivatedRoute

Component中。

class ComponentClass{
  activeFragment = this.route.fragment.pipe(share()); 
  constructor(public route: ActivatedRoute){}
}

template中,按如下所示使用它。

<li [class.active]="(activeFragment | async)==='inicio'">
    <a routerLink="/sitio" fragment="inicio">Inicio</a>
</li>
<li [class.active]="(activeFragment | async)==='invierte'">
    <a routerLink="/sitio" fragment="invierte">Invierte</a>
</li>
<li [class.active]="(activeFragment | async)==='contacto'">
    <a routerLink="/sitio" fragment="contacto">Contacto</a>
</li

我不确定这里的share运算符。我没有研究它是否默认为多播。 让我知道您是否有答案。

答案 4 :(得分:0)

Omar 建议的解决方案有效,但是,当我有一个片段在名称中包含另一个片段的名称时,就会产生冲突。

例如,一个叫做tab的片段和另一个叫做table的片段,当激活table片段时,tab也会被激活,因为它的名字中有tab这个词。

我对此解决方案进行了一些更改,希望对其他人有所帮助。

component.ts

import { ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute){}

isSectionActive(section: string): boolean {
  let element = false;
  this.route.fragment.subscribe((fragment: string) => {
    element = fragment === section.split("#").pop();
  });
  return element;
}

component.html

<button type="button" class="item" [routerLink]="['/components/tutorial']" [fragment]="fragmentName" [class.active]="isSectionActive(fragmentName)">{{fragmentName}}</button>