Добавить и удалить элементы класса на ViewChild в Angular - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть вкладки в приложении, активная вкладка должна соответствовать уровню пользователя. Я создал viewChild для добавления его активного класса, но у меня не получилось, и появляется следующая ошибка:

ERROR TypeError: Cannot read property 'querySelector' of undefined
    at TrainingComponent.push../src/app/views/training/training.component.ts.TrainingComponent.ngAfterViewInit 

Мой компонент:

  @ViewChild('tabExplorator') tabExplorator: ElementRef;
  @ViewChild('tabEspecialist') tabEspecialist: ElementRef;

  constructor(public timeguard:TimeguardService, public router: Router,  public progressbar:ProgressBarService, public geo: GeolocationService, public dl: DatalayerService<GameDimensionSet>, public database: DatabaseService < Fase > , public auth: AuthService) {}

  ngAfterViewInit () {
    //assigning an element to a variable
    let tabExplorator = this.tabExplorator.nativeElement.querySelector('tabExplorator')
    let tabEspecialist = this.tabEspecialist.nativeElement.querySelector('tabEspecialist')

    if(this.auth.User.nivel == 'EXPLORADOR' && tabExplorator.classList.contains('active')){
      tabExplorator.classList.remove('active')
      tabEspecialist.classList.add('active')
    }

  }

Мой HTML:

 <ul class="tabs ranking-letra-tabs tabs-icon">
      <li class="tab col s3 cor-explorador alinha-texto">
        <a href="#ranking-nivel1" #tabExplorator>
          <div>
            <i class="material-icons cor-estrelas tabs-icon">star</i>
          </div>
          <div class="">
            {{NIVEL1}}
          </div>
        </a>
      </li>

      <li class="tab col s3 cor-especialista alinha-texto">
        <a href="#ranking-nivel2" #tabEspecialist>
          <div>
            <i class="material-icons cor-estrelas estrela-tabs-1">star</i>
            <i class="material-icons cor-estrelas estrela-tabs-2">star</i>
          </div>
          <div>
            {{NIVEL2}}
          </div>
        </a>
      </li>
    </ul>

Я использую материализовать, согласно документации:

"Показать содержимое вкладки, которая соответствует вкладке с идентификатором"

instance.select('tab_id');

Может ли это помочь?

Ответы [ 2 ]

0 голосов
/ 04 апреля 2020

Я бы порекомендовал вам прочитать немного о ngClass для добавления или удаления класса в элементе с выражениями. В вашем коде я написал бы код вроде:

 <ul class="tabs ranking-letra-tabs tabs-icon">
  <li class="tab col s3 cor-explorador alinha-texto">
    <a href="#ranking-nivel1" [class.active]="isUserExplorer">
      <div>
        <i class="material-icons cor-estrelas tabs-icon">star</i>
      </div>
      <div class="">
        {{NIVEL1}}
      </div>
    </a>
  </li>

  <li class="tab col s3 cor-especialista alinha-texto">
    <a href="#ranking-nivel2" [class.active]="!isUserExplorer">
      <div>
        <i class="material-icons cor-estrelas estrela-tabs-1">star</i>
        <i class="material-icons cor-estrelas estrela-tabs-2">star</i>
      </div>
      <div>
        {{NIVEL2}}
      </div>
    </a>
  </li>
</ul>

Адаптируя необходимые логики c в 'isUserExplorer', а в вашем коде машинописи:

get isUserExplorer(): boolean { return this.auth.User.nivel === 'EXPLORADOR'; }

constructor(public timeguard:TimeguardService, public router: Router,  public progressbar:ProgressBarService, public geo: GeolocationService, public dl: DatalayerService<GameDimensionSet>, public database: DatabaseService < Fase > , public auth: AuthService) {}

I рекомендуем не использовать @ViewChild для предотвращения нарушения инкапсуляции элементов. В руководстве по стилю вы можете просмотреть [class.syntax] и другие хаки, чтобы иметь красивый код xd

Надеюсь, это поможет

0 голосов
/ 04 апреля 2020

Вы можете использовать Renderer2 вместе с ElementRef для переключения классов элементов. Он использует функции рендерера addClass() и removeClass(), основанные на том, содержит ли элемент класс active. Логическое значение, обозначающее текущее состояние, получается с использованием функции element.classList.contains('active'). Попробуйте следующий

import { Component, ViewChild, ElementRef, Renderer2 } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  @ViewChild('tabExplorator') tabExplorator: ElementRef;

  constructor(private renderer: Renderer2) { }

  toggleBackground() {
    const active = this.tabExplorator.nativeElement.classList.contains('active');

    this.renderer[active ? 'removeClass' : 'addClass'](this.tabExplorator.nativeElement, 'active');
  }
}

Рабочий пример: Stackblitz

...