【发布时间】:2016-10-24 06:06:48
【问题描述】:
在我环游世界互联网的过程中,尤其是现在的angular.io style docs,我发现很多对@HostBinding 和@HostListener 的引用。看起来它们非常基础,但不幸的是,目前它们的文档有点粗略。
谁能解释一下它们是什么,它们是如何工作的,并举例说明它们的用法?
【问题讨论】:
在我环游世界互联网的过程中,尤其是现在的angular.io style docs,我发现很多对@HostBinding 和@HostListener 的引用。看起来它们非常基础,但不幸的是,目前它们的文档有点粗略。
谁能解释一下它们是什么,它们是如何工作的,并举例说明它们的用法?
【问题讨论】:
你检查过这些官方文档吗?
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 {}
【讨论】:
给这个主题增加混乱的一件事是装饰器的概念不是很清楚,当我们考虑类似......
@HostBinding('attr.something')
get something() {
return this.somethingElse;
}
它有效,因为它是get accessor。你不能使用等效的函数:
@HostBinding('attr.something')
something() {
return this.somethingElse;
}
否则,使用@HostBinding 的好处是它可以确保在绑定值更改时运行更改检测。
【讨论】:
@HostBinding 的另一个好处是,如果您的绑定直接依赖于输入,您可以将其与 @Input 结合使用,例如:
@HostBinding('class.fixed-thing')
@Input()
fixed: boolean;
【讨论】:
@Input()分享使用示例?
@HostBinding 有何不同。什么时候需要使用@Input?
这是一个基本的悬停示例。
组件的模板属性:
模板
<!-- 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" ;
}
}
【讨论】:
@Hostlistnening 基本上处理宿主元素say(一个按钮),它监听用户的动作并执行特定的功能,sayalert("Ahoy!") 而@Hostbinding 则相反。在这里,我们在内部监听该按钮上发生的变化(比如当它被单击时,类发生了什么),然后我们使用该变化来做其他事情,比如发出特定的颜色。
考虑一下您想在组件上制作收藏图标的场景,现在您知道您必须知道该项目是否已被收藏并更改其类,我们需要一种方法来确定这一点。这正是@Hostbinding 的用武之地。
在哪里需要知道用户实际执行了什么操作,这就是@Hostlistening 的作用
【讨论】:
帮助我记住他们所做的快速提示 -
HostBinding('value') myValue; 与[value]="myValue" 完全相同
和
HostListener('click') myClick(){ } 与(click)="myClick()" 完全相同
HostBinding 和 HostListener 写在指令中
其他的 (...) 和 [..] 写在(组件的)模板中。
【讨论】:
@HostListener 是当你在 DOM 上没有任何东西用于典型事件绑定时的方法,比如我的键盘输入。
@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';
}
}
在上面的例子中发生了以下情况:
AppComponent 类中的color 属性绑定到组件上的style.color 属性。所以每当color 属性更新时,我们组件的style.color 属性也会更新@Directive中的用法:虽然它可以用于组件,但这些装饰器通常用于属性指令中。当在@Directive 中使用时,主机会更改放置指令的元素。例如看看这个组件模板:
<p p_Dir>some paragraph</p>
这里 p_Dir 是<p> 元素上的指令。在指令类中使用@HostBinding 或@HostListener 时,主机现在将引用<p>。
【讨论】:
// 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>
【讨论】:
方法装饰器:
@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>
【讨论】: