cobolstinks
cobolstinks

Reputation: 7153

Angular2 Detect if element in template view has class

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.

Upvotes: 31

Views: 55284

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658067

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();
  }
} 

Upvotes: 57

Related Questions