Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 Detect if element in template view has class

Tags:

angular

We're using bootstrap, and sometimes it automatically adds classes to DOM elements. What is the best way to attach to these elements and detect when a particalr css class is added to a component template child element?

Say i have this component:

import { Component, ViewChild, ElementRef } from '@angular/core';
import { HeaderService } from './header.service';

@Component({
    selector: 'header-comp',
    templateUrl: './Home/RenderLayoutHeader'
})

export class HeaderLayoutComponent {
    constructor(private _headerService: HeaderService) { }
}

And this is a portion of my view template:

<header-comp>      
<li class="nav-header-icon-list-item">
                        <div class="overlay-dropdown dropdown" id="patientDDL">
                            <button  class="btn btn-default dropdown-toggle session-menu-container" type="button" id="session-dropdown-menu" data-toggle="dropdown" data-backdrop="true" data-dismiss="modal"  aria-haspopup="true" aria-expanded="false">
                                <img data-initials="ER" src="https://lorempixel.com/40/40/abstract/" class="img-circle session-user-profile-img">

How do i detect in my component when bootstrap adds "open" class to #patientDDL element and execute a function in my component?

Thanks!

EDIT: I modified my component to this per Gunter's solution but I'm getting a null reference when i don't precede the criteria with a null check)

import { Component, ViewChild, ElementRef, DoCheck } from '@angular/core';
import { HeaderService } from './header.service';

@Component({
    selector: 'header-comp',
    templateUrl: './Home/RenderLayoutHeader'
})

export class HeaderLayoutComponent implements DoCheck {

    @ViewChild('patientDDL') patientDropDownList: ElementRef;

    constructor(private _headerService: HeaderService) { }

    ngDoCheck() {
        console.log('ngDoCheck called');
        if (this.patientDropDownList && this.patientDropDownList.nativeElement.classList.contains('open')) {
            this._headerService.setPatientDDLOpen(true);
        } else {
            this._headerService.setPatientDDLOpen(false);
        }

    }
}

Also the console statment is logged 4 times while the template loads but then it is never invoked again, even after the class has been added/removed multiple times.

This is angular2 rc1 not sure if that is relevant.

like image 928
cobolstinks Avatar asked Jun 24 '16 17:06

cobolstinks


1 Answers

Add a template variable to be able to query the element.

<div #patientDDL class="overlay-dropdown dropdown" id="patientDDL">

Query the element

@ViewChild('patientDDL') patientDDL:ElementRef;

Implement ngDoCheck() to run the check whether the class was added when change detection runs:

ngDoCheck() {
  if(patientDDL.nativeElement.classList.contains('open')) {
    this.doSomething();
  }
} 

or on some specific event

@HostListener('click', ['$event'])
clickHandler(event) {
  if(patientDDL.nativeElement.classList.contains('open')) {
    this.doSomething();
  }
} 
like image 64
Günter Zöchbauer Avatar answered Oct 18 '22 08:10

Günter Zöchbauer