了解 @HostBinding 如何在 angular 中为 toggleClass 指令工作

understanding how @HostBinding works in angular for toggleClass directive

我遇到了以下 angular 指令:

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

在线浏览代码时,基本上代码只在使用该指令的元素上切换 open class,因此可以像这样使用该指令:

<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>

现在我不明白的是指令中的以下代码行:

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

它到底是做什么的,它的作用是什么?我不太理解上面的代码行。有人可以解释一下吗?

看看这个link。总结一下:

@HostBinding 装饰器可让您更新指令的宿主元素的属性。据我了解,这意味着 Angular 变化检测将评估由它修饰的变量(表达式)并将变化传播到宿主元素中 'bind' 的属性(add\remove class 在你的情况下)。

@HostBinding 允许您为指令的宿主元素定义绑定。你可能知道有一个 special binding syntax for the class 看起来像这样:

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

您可以在 中阅读实施细节。

在您的示例中,li 元素是宿主元素并且表达式是 isOpen 因此您引用的宿主绑定实质上定义了以下内容:

<li class="dropdown" appDropdown [class.open]="isOpen">

注意不要在指令中将 @HostBindingRenderer2 混合使用以更改 DOM 样式。不知道为什么,但得到了意想不到的结果。

示例如下:

//: 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]");
  }

}