understanding how @HostBinding works in angular for toggleClass directive
Asked Answered
C

3

6

I came across the following angular directive:

import { Directive , HostListener , HostBinding } from '@angular/core';

@Directive({
    selector: '[appDropdown]'
})

export class DropdownDirective {
    @HostBinding('class.open') isOpen = false;

    @HostListener('click') toggleOpen() {
        this.isOpen = !this.isOpen;
    }
}

While surfing code online , basically the code only toggles the open class on the element the directive is used on , so this directive can be used like so:

<ul class="nav navbar-nav navbar-right">
    <li class="dropdown" appDropdown>
        <a href="#" class="dropdown-toggle" role="button">Manage <span class="caret"></span></a>
        <ul class="dropdown-menu">
            <li><a href="#">Save Data</a></li>
            <li><a href="#">Fetch Data</a></li>
        </ul>
    </li>
</ul>

Now what i don't understand is the below line of code in the directive:

 @HostBinding('class.open') isOpen = false;

Whats exactly is it doing and how exactly does it function ? I am not quite understanding the above line of code. can somebody please explain ?

Connolly answered 30/10, 2017 at 18:49 Comment(0)
L
5

@HostBinding allows you to define a binding for a host element of your directive. As you probably know there's a special binding syntax for the class that looks like this:

<element [class.class-name]="expression">...</element>

You can read specifics of implementation in How [class] [attr] [style] directives work.

In your example the li element is the host element and the expression is isOpen so the host binding your referenced essentially defines the following:

<li class="dropdown" appDropdown [class.open]="isOpen">
Lowdown answered 31/10, 2017 at 5:51 Comment(0)
Y
2

Have a look at this link. To sum it up:

@HostBinding decorator lets you update properties on the host element of the directive. What that means, as far as i understand, is that Angular change detection will evaluate the variables (expresions) decorated by it and propagate changes to the attributes you 'bind' in the host element (add\remove class in your case).

Yb answered 30/10, 2017 at 19:28 Comment(0)
G
0

Be careful to not mix @HostBinding with Renderer2 in a directive to change DOM style. Not sure why, but gets unexpected results.

Example Below:

//: WORKS: ENTER_A + EXIT_A
//: WORKS: ENTER_B + EXIT_B

//: FAILS: ENTER_A + EXIT_B
//: FAILS: ENTER_B + EXIT_A

import {
  Directive    ,

  HostBinding  ,
  HostListener ,

  Renderer2    ,
  ElementRef   } from '@angular/core';

@Directive({
  selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective {

  constructor(private ER: ElementRef, private REN:Renderer2 ) {}

  changeBgColor( color_string: string ){
    this.REN.setStyle( this.ER.nativeElement, 'background-color', color_string);
  }

  //Use CamelCase because DOM does not understand "background-color"
  @HostBinding('style.backgroundColor') backgroundColor: string = "blue";

  @HostListener('mouseenter') mouseover(ED: Event){
    //this.changeBgColor( "magenta");  //<<<<<< [ ENTER_A ]
    this.backgroundColor = 'magenta';  //<<<<<< [ ENTER_B ]
    console.log("[MOUSE_ENTER]");
  }

  @HostListener('mouseleave') mouseleave(ED: Event){
    //this.changeBgColor("green"); //<<<<<<<<<< [ EXIT_A ]
    this.backgroundColor = 'green'; //<<<<< [ EXIT_B ]
    console.log("[MOUSE_LEAVE]");
  }

}
Goto answered 25/11, 2017 at 19:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.