【问题标题】:@HostBinding and @HostListener: what do they do and what are they for?@HostBinding 和@HostListener:它们是做什么的,它们的用途是什么?
【发布时间】:2016-10-24 06:06:48
【问题描述】:

在我环游世界互联网的过程中,尤其是现在的angular.io style docs,我发现很多对@HostBinding@HostListener 的引用。看起来它们非常基础,但不幸的是,目前它们的文档有点粗略。

谁能解释一下它们是什么,它们是如何工作的,并举例说明它们的用法?

【问题讨论】:

    标签: angular angular-services


    【解决方案1】:

    你检查过这些官方文档吗?

    HostListener - 声明一个主机监听器。当宿主元素发出指定的事件时,Angular 会调用被修饰的方法。

    @HostListener - 将侦听由 @HostListener 声明的宿主元素发出的事件。

    HostBinding - 声明一个主机属性绑定。 Angular 在更改检测期间自动检查主机属性绑定。如果绑定发生变化,它将更新指令的宿主元素。

    @HostBinding - 将属性绑定到宿主元素,如果绑定发生变化,HostBinding 将更新宿主元素。


    注意:这两个链接最近都被删除了。在链接返回之前,样式指南的“HostBinding-HostListening”部分可能是一个有用的替代方案。


    这里有一个简单的代码示例来帮助理解这意味着什么:

    演示:这是 plunker 中的演示 - "A simple example about @HostListener & @HostBinding"

    • 此示例将role 属性(使用@HostBinding 声明)绑定到主机元素
      • 回想一下role 是一个属性,因为我们使用的是attr.role
      • 当您在开发者工具中查看<p myDir> 时,它会变为<p mydir="" role="admin">
    • 然后它侦听使用@HostListener 声明的onClick 事件,附加到组件的宿主元素,每次单击都会更改role
      • 点击<p myDir>时的变化是它的开始标签从<p mydir="" role="admin">变为<p mydir="" role="guest">并返回。

    directives.ts

    import {Component,HostListener,Directive,HostBinding,Input} from '@angular/core';
    
    @Directive({selector: '[myDir]'})
    export class HostDirective {
      @HostBinding('attr.role') role = 'admin'; 
      @HostListener('click') onClick() {
        this.role= this.role === 'admin' ? 'guest' : 'admin';
      }
    }
    

    AppComponent.ts

    import { Component,ElementRef,ViewChild } from '@angular/core';
    import {HostDirective} from './directives';
    
    @Component({
    selector: 'my-app',
    template:
      `
      <p myDir>Host Element 
        <br><br>
    
        We have a (HostListener) listening to this host's <b>click event</b> declared with @HostListener
    
        <br><br>
    
        And we have a (HostBinding) binding <b>the role property</b> to host element declared with @HostBinding 
        and checking host's property binding updates.
    
        If any property change is found I will update it.
      </p>
    
      <div>View this change in the DOM of the host element by opening developer tools,
        clicking the host element in the UI. 
    
        The role attribute's changes will be visible in the DOM.</div> 
        `,
      directives: [HostDirective]
    })
    export class AppComponent {}
    

    【讨论】:

    • 这个装饰器还在使用吗,似乎链接已从 angular2 文档中删除
    • 是的,它仍在使用,但让我确认一次。我会更新你,如果我能找出别的东西。
    • @Mr.EasyAnswersMcFly 用注释和链接更新了答案。请注意,仍然没有适当的文档。
    • @MuhammadSaleh 滚动很难说它是如何计数和计算的......但可以肯定的是每个实例都会有一个单独的监听器
    【解决方案2】:

    给这个主题增加混乱的一件事是装饰器的概念不是很清楚,当我们考虑类似......

    @HostBinding('attr.something') 
    get something() { 
        return this.somethingElse; 
     }
    

    它有效,因为它是get accessor。你不能使用等效的函数:

    @HostBinding('attr.something') 
    something() { 
        return this.somethingElse; 
     }
    

    否则,使用@HostBinding 的好处是它可以确保在绑定值更改时运行更改检测。

    【讨论】:

      【解决方案3】:

      @HostBinding 的另一个好处是,如果您的绑定直接依赖于输入,您可以将其与 @Input 结合使用,例如:

      @HostBinding('class.fixed-thing')
      @Input()
      fixed: boolean;
      

      【讨论】:

      • 您能否与@Input()分享使用示例?
      • 示例就在我的回答中,您只需一个接一个地编写两个装饰器,顺序应该无关紧要
      • 我认为我缺少的是这与仅使用 @HostBinding 有何不同。什么时候需要使用@Input
      【解决方案4】:

      这是一个基本的悬停示例。

      组件的模板属性:

      模板

      <!-- attention, we have the c_highlight class -->
      <!-- c_highlight is the selector property value of the directive -->
      
      <p class="c_highlight">
          Some text.
      </p>
      

      还有我们的指令

      import {Component,HostListener,Directive,HostBinding} from '@angular/core';
      
      @Directive({
          // this directive will work only if the DOM el has the c_highlight class
          selector: '.c_highlight'
       })
      export class HostDirective {
      
        // we could pass lots of thing to the HostBinding function. 
        // like class.valid or attr.required etc.
      
        @HostBinding('style.backgroundColor') c_colorrr = "red"; 
      
        @HostListener('mouseenter') c_onEnterrr() {
         this.c_colorrr= "blue" ;
        }
      
        @HostListener('mouseleave') c_onLeaveee() {
         this.c_colorrr = "yellow" ;
        } 
      }
      

      【讨论】:

      • 我不认为这个接受的答案是对所提问题的回答。你愿意提供一些解释吗?就像 c_colorrr、c_onEnterrr()、c_onLeaveeee 在这个特定的代码 sn-p 中所做的一样?
      • 我认为它应该将鼠标进入事件的颜色更改为蓝色,并将鼠标离开事件的颜色更改为黄色。
      • 你把指令放在标记中的什么位置?似乎您会将它放在 body 标记上,但这将在根组件之外。如果您对此答案感到困惑,此链接可能会有所帮助ng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding
      • @mtpultz 在课堂上。
      【解决方案5】:

      行话少的理论

      @Hostlistnening 基本上处理宿主元素say(一个按钮),它监听用户的动作并执行特定的功能,sayalert("Ahoy!") 而@Hostbinding 则相反。在这里,我们在内部监听该按钮上发生的变化(比如当它被单击时,类发生了什么),然后我们使用该变化来做其他事情,比如发出特定的颜色。

      示例

      考虑一下您想在组件上制作收藏图标的场景,现在您知道您必须知道该项目是否已被收藏并更改其类,我们需要一种方法来确定这一点。这正是@Hostbinding 的用武之地。

      在哪里需要知道用户实际执行了什么操作,这就是@Hostlistening 的作用

      【讨论】:

      • 这很混乱,装饰器名称不准确。
      【解决方案6】:

      帮助我记住他们所做的快速提示 -

      HostBinding('value') myValue;[value]="myValue" 完全相同

      HostListener('click') myClick(){ }(click)="myClick()" 完全相同


      HostBindingHostListener 写在指令中 其他的 (...)[..] 写在(组件的)模板中。

      【讨论】:

      • 啊,多亏了这个答案,它和我一起点击(双关语)。 @HostListener 是当你在 DOM 上没有任何东西用于典型事件绑定时的方法,比如我的键盘输入。
      • 简单易懂。谢谢....
      • 最高水平的教学发生在老师帮助学生“连接点”时。谢谢你的回答!
      【解决方案7】:

      总结:

      • @HostBinding:这个装饰器将一个类属性绑定到宿主元素的一个属性上。
      • @HostListener:这个装饰器将一个类方法绑定到宿主元素的一个事件上。

      示例:

      import { Component, HostListener, HostBinding } from '@angular/core';
      
      @Component({
        selector: 'app-root',
        template: `<p>This is nice text<p>`,
      })
      export class AppComponent  {
      
        @HostBinding('style.color') color; 
      
        @HostListener('click')
        onclick() {
          this.color =  'blue';
        }
      
      }
      

      在上面的例子中发生了以下情况:

      • 一个事件监听器被添加到 click 事件中,当组件内任何地方发生 click 事件时将触发该事件监听器
      • AppComponent 类中的color 属性绑定到组件上的style.color 属性。所以每当color 属性更新时,我们组件的style.color 属性也会更新
      • 结果是每当有人点击组件时,颜色就会更新。

      @Directive中的用法:

      虽然它可以用于组件,但这些装饰器通常用于属性指令中。当在@Directive 中使用时,主机会更改放置指令的元素。例如看看这个组件模板:

      <p p_Dir>some paragraph</p>
      

      这里 p_Dir 是&lt;p&gt; 元素上的指令。在指令类中使用@HostBinding@HostListener 时,主机现在将引用&lt;p&gt;

      【讨论】:

        【解决方案8】:
        // begginers
        @Component({
          selector: 'custom-comp',
          template: ` <div class="my-class" (click)="onClick()">CLICK ME</div> `,
        })
        export class CustomComp {
          onClick = () => console.log('click event');
        }
        
        // pros
        @Component({
          selector: 'custom-comp',
          template: ` CLICK ME `,
        })
        export class CustomComp {
          @HostBinding('class') class = 'my-class';
          @HostListener('click') onClick = () => console.log('click event');
        }
        
        // experts
        @Component({
          selector: 'custom-comp',
          template: ` CLICK ME `,
          host: {
            class: 'my-class',
            '(click)': 'onClick()',
          },
        })
        export class CustomComp {
          onClick = () => console.log('click event');
        }
        
        ------------------------------------------------
        The 1st way will result in:
        <custom-comp>
           <div class="my-class" (click)="onClick()">
              CLICK ME
           <div>
        </custom-comp>
        
        The last 2 ways will result in:
        <custom-comp class="my-class" (click)="onClick()">
           CLICK ME
        </custom-comp>
        

        【讨论】:

        • 感谢您提供答案。您能否编辑您的答案以包括对您的代码的解释?这将有助于未来的读者更好地了解正在发生的事情,尤其是那些刚接触该语言并难以理解概念的社区成员。
        【解决方案9】:

        方法装饰器:

        @HostBinding:将自定义逻辑动态绑定到 Host 元素

         @HostBinding('class.active')
         activeClass = false;
        

        @HostListen:监听主机元素上的事件

        @HostListener('click')
         activeFunction(){
            this.activeClass = !this.activeClass;
         }
        

        主机元素:

          <button type='button' class="btn btn-primary btn-sm" appHost>Host</button>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-09-04
          • 2017-02-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-18
          相关资源
          最近更新 更多