【问题标题】:Add and remove elements class on ViewChild in Angular在 Angular 中的 ViewChild 上添加和删除元素类
【发布时间】:2020-04-03 23:53:33
【问题描述】:

我的应用程序中有标签,活动标签必须对应于用户的级别。我创建了一个 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>

根据文档,我正在使用物化:

"显示与该 id 选项卡对应的选项卡内容"

instance.select('tab_id');

有帮助吗?

【问题讨论】:

    标签: angular typescript tabs materialize viewchild


    【解决方案1】:

    您可以使用Renderer2ElementRef 来切换元素类。它根据元素是否包含active 类使用渲染器的addClass()removeClass() 函数。表示当前状态的布尔值是使用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

    【讨论】:

      【解决方案2】:

      我建议您阅读一些关于 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>
      

      在“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) {}
      

      我建议您不要使用 @ViewChild 来防止元素违反封装。 在style guide 你可以查看 [class.syntax] 和其他 hack 以获得漂亮的代码 xd

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-12
        • 1970-01-01
        • 2019-10-20
        • 1970-01-01
        • 2015-08-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多