【问题标题】:understanding how @HostBinding works in angular for toggleClass directive了解 @HostBinding 如何以角度为 toggleClass 指令工作
【发布时间】:2018-04-11 20:22:28
【问题描述】:

我遇到了以下角度指令:

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类,因此可以像这样使用该指令:

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

它到底在做什么以及它是如何运作的?我不太了解上面的代码行。有人可以解释一下吗?

【问题讨论】:

    标签: angular angular2-directives


    【解决方案1】:

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

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

    您可以在How [class] [attr] [style] directives work 中阅读实现细节。

    在您的示例中,li 元素是主机元素,表达式是 isOpen,因此您引用的主机绑定基本上定义了以下内容:

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

    【讨论】:

      【解决方案2】:

      看看这个link。总结一下:

      @HostBinding 装饰器允许您更新指令宿主元素的属性。据我了解,这意味着Angular更改检测将评估由它修饰的变量(表达式)并将更改传播到您在宿主元素中“绑定”的属性(在您的情况下添加\删除类)。

      【讨论】:

        【解决方案3】:

        注意不要在指令中混合 @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]");
          }
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-01
          • 2019-03-28
          • 1970-01-01
          • 2018-04-30
          • 1970-01-01
          • 2017-05-10
          • 2015-01-06
          • 1970-01-01
          相关资源
          最近更新 更多