Angular 2 точный RouterLinkActive, включая фрагменты?

При использовании routerLink и routerLinkActive для применения 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>

Три разных URL-адреса, приведенные выше, следующие:

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

Но при каждом нажатии любой из них все они отмечены как активные (поскольку они соответствуют информации routerLink="/sitio" и fragment=*), которые не включены в проверку. Это приводит к тому, что панель навигации выглядит так: нажав на любой из них:

введите описание изображения здесь

Любые идеи о том, как это сделать?

Ответ 1

Существует открытая проблема для поддержки https://github.com/angular/angular/issues/13205

routerLinkActive - простая директива. Вы могли бы создать клон самостоятельно с этой расширенной функциональностью.

Ответ 2

Я просто подумал, что поставил бы, как я его решил, если кто-то столкнется с одной и той же проблемой: отслеживать текущий раздел сайта и использовать привязку класса через функцию в компоненте вместо 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.:)

Ответ 3

Сделать подход Омара Трехо проще. Вместо того, чтобы подписываться на Маршрут, я обновил isSectionActive, чтобы посмотреть на location.href, чтобы он работал.

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

Ответ 4

Я изо всех сил [routerLinkActiveOptions]="{ exact: true }" работать с [routerLinkActiveOptions]="{ exact: true }" даже на Angular 7.

Итак, я использовал следующую уловку, чтобы решить эту проблему. Ответ ActivatedRoute.

в Component.

class ComponentClass{
  public 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 оператора здесь. Я не смотрел на это, если его многоадресная по умолчанию. Дайте мне знать, если у вас есть ответ на этот вопрос.