Можем ли мы выбрать элемент <a>, когда его routerLink активен в angular?

Я хочу выбрать элемент <a> по className, когда его ссылка на маршрутизатор активна, но он возвращает null

Код navbar.component.html:

<nav class = "profile-navbar">
  <ul>
    <li class = "posts-item">
      <a
        [routerLink] = "['/app/profile', username, 'posts']"
        routerLinkActive = "active-link"
        >Posts</a
      >
    </li>
    <li class = "images-item">
      <a
        [routerLink] = "['/app/profile', username, 'images']"
        routerLinkActive = "active-link"
        >Images</a
      >
    </li>
  </ul>
</nav>

Код navbar.component.ts:

import { AfterViewInit, Component, OnInit } from '@angular/core';

@Component({
  selector: 'profile-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit, AfterViewInit {
  
  constructor() { 
  }
  
  ngOnInit(): void {
  }
  
  ngAfterViewInit(): void {
    const activeLink = document.querySelector('.active-link');
    console.info(activeLink)
  }

}

Как я могу выбрать элемент, основанный на классе routerLinkActive?

Зачем вам нужен доступ к этому элементу, если я могу спросить?

MikeOne 19.03.2022 22:08

Я хочу добавить индикатор активной ссылки, как стиль в этом codepen codepen.io/ohsoren/pen/QNoQwX

Asmaa Mahmoud 19.03.2022 22:21

@AsmaaMahmoud, почему бы не использовать .active-link::after{......}?

Eliseo 20.03.2022 22:01

@Eliseo, индикатор не является частью самой активной ссылки, это отдельный элемент, который перемещается под всеми ними.

Asmaa Mahmoud 21.03.2022 09:35

@AsmaaMahmoud, вы можете использовать ViewChildren, проверьте мой ответ :)

Eliseo 21.03.2022 15:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
103
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы не можете использовать этот LifeCycleHook вместо этого, попробуйте ngDoCheck() или прослушайте изменения маршрута (Как обнаружить изменение маршрута в Angular?) и сделайте свой выбор на основе события или, что еще лучше, просто используйте в своем файле .css:

a.active {
/* your style */
}

Если вы просто хотите стилизовать его, обычно его не нужно выбирать, но в вашем случае с расчетом translate3d и scaleX я не уверен...

Он возвращает первую ссылку с атрибутом routerLinkActive со значением «активная ссылка».

Asmaa Mahmoud 20.03.2022 08:00

Извините, я пропустил это, я только что обновил свой ответ!

Perry45 20.03.2022 09:35

Нет проблем, я только что использовал querySellectorAll, и он отлично работает, но мне было интересно, есть ли способ получить только активную ссылку.

Asmaa Mahmoud 20.03.2022 10:08

И почему выбор элемента с именем класса не работает?

Asmaa Mahmoud 20.03.2022 10:09

Извините еще раз, я неправильно понял ваш вопрос. Класс следует применять, но только после ngAfterViewInit. Так что просто используйте ngAfterViewChecked или просто используйте селектор css.

Perry45 20.03.2022 21:24

Спасибо большое, вот так ngAfterViewChecked(), но я думаю нехорошо вызывать функцию позиционирования индикатора внутри ngAfterViewChecked(), не так ли?

Asmaa Mahmoud 21.03.2022 09:45

@AsmaaMahmoud Вы должны использовать ngDoCheck() и вызывать свой метод оттуда или, что еще лучше, использовать событие маршрутизатора так, как предложил Элисео.

Perry45 21.03.2022 18:37
Ответ принят как подходящий

Чтобы получить серию «div», вы можете использовать ссылочную переменную шаблона и ViewChildren. Когда у вас есть ViewChildren, вы можете найти элемент с классом или другим свойством.

В случае с routerLinks подход аналогичен, но вы можете иметь в ViewChildren [routerLinksActive, видимый как "ElementRef" и видящийся как "RouterLinkActive"

Некоторым нравится

  //links are the "RouterLinkActive"
  @ViewChildren(RouterLinkActive) links:QueryList<RouterLinkActive>
  
  //lisk are the "RouterLinkAvtive" but seeing as ElementRef
  @ViewChildren(RouterLinkActive,{read:ElementRef}) linksElements:QueryList<ElementRef>
  @ViewChild('indicator') indicator:ElementRef
  constructor(private router: Router) {}
  ngOnInit() {
    this.router.events.pipe(
       filter(x=>x instanceof NavigationEnd),
       startWith(null)).subscribe(res=>{

      //we need enclosed in a setTimeout because when the event NavigationEnd
      //happens, Angular are not add the class "active-links"
      // nor link isActive=true
      setTimeout(()=>{

        //first find the "index" in the QueryList
        const index=(this.links.map(
          (x:RouterLinkActive,i:number)=>({isActive:x.isActive,index:i}))          
          .find(x=>x.isActive) || {index:-1}).index
  
        //it's the same index in the ElementRef
        if (index>=0)
        {
          const el=this.linksElements.find((_,i)=>i==index)
          
          //We use the "el" to change the style.top of the indicator
           this.indicator.nativeElement.style.top=
                       el.nativeElement.offsetTop+'px'
        }
        else
        {
          this.indicator.nativeElement.style.top='-100px'
        }
      })
    })
  }

Где

<nav class = "profile-navbar">
<ul>
  <li class = "posts-item">
    <a
      [routerLink] = "['/hello']"
      routerLinkActive = "active-link"
      >Posts</a
    >
  </li>
  <li class = "images-item">
    <a
      [routerLink] = "['/by']"
      routerLinkActive = "active-link"
      >Images</a
    >
  </li>
</ul>
<div #indicator class = "indicator"></div>
</nav>

как показано в этот стекблиц

Другие вопросы по теме