@HostBinding 和@HostListener:它们做什么,有什么用?
@HostBinding and @HostListener: what do they do and what are they for?
我在世界各地的互联网上闲逛,现在尤其是在 angular.io style docs 上,我发现很多对 @HostBinding
和 @HostListener
的引用。看起来它们非常基础,但不幸的是,目前它们的文档有点粗略。
任何人都可以解释一下它们是什么、它们是如何工作的并举例说明它们的用法吗?
你查过这些官方文档了吗?
HostListener - 声明主机侦听器。 Angular 将在宿主元素发出指定事件时调用装饰方法。
@HostListener
- 将监听由 @HostListener
.
声明的宿主元素发出的事件
HostBinding - 声明主机 属性 绑定。 Angular 在更改检测期间自动检查主机 属性 绑定。如果绑定更改,它将更新指令的主机元素。
@HostBinding
- 将 属性 绑定到宿主元素,如果绑定更改,HostBinding
将更新宿主元素。
注意: 这两个链接最近都已删除。在链接 return 之前,样式指南的“HostBinding-HostListening”部分可能是有用的替代方法。
下面是一个简单的代码示例,可以帮助理解这意味着什么:
DEMO:这是 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;
这是一个基本的悬停示例。
组件模板 属性:
模板
<!-- 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 基本上处理主机元素,比如(一个按钮)监听用户的动作并执行某个功能,比如 alert("Ahoy!") 而 @Hostbinding 则相反。在这里,我们在内部监听该按钮发生的变化(比如当它被点击时 class 发生了什么),我们使用该变化来做其他事情,比如发出特定的颜色。
例子
想想你想在一个组件上制作一个收藏图标的场景,现在你知道你必须知道这个项目是否已经被收藏了 class 改变了,我们需要一个方法确定这一点。这正是 @Hostbinding 的用武之地。
在需要知道用户实际执行了什么操作的地方,@Hostlistening 就派上用场了
帮助我记住他们做什么的快速提示 -
HostBinding('value') myValue;
与 [value]="myValue"
完全相同
和
HostListener('click') myClick(){ }
与 (click)="myClick()"
完全相同
HostBinding
和HostListener
写在指令中
其他的 (...)
和 [..]
写在(组件的)模板中。
总结:
@HostBinding
:这个装饰器将class属性绑定到宿主元素的属性。
@HostListener
:这个装饰器绑定了一个class方法到宿主元素的一个事件。
示例:
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
class中的color
属性绑定到组件上的style.color
属性。因此,每当更新 color
属性 时,组件 的 style.color
属性 也会更新
- 结果将是每当有人单击该组件时颜色就会更新。
在@Directive
中的用法:
虽然它可以用在组件上,但这些装饰器通常用在属性指令中。当在 @Directive
中使用时,主机会更改放置指令的元素。例如看看这个组件模板:
<p p_Dir>some paragraph</p>
这里 p_Dir 是 <p>
元素上的指令。当在指令 class 中使用 @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:动态绑定自定义逻辑到主机元素
@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>
我在世界各地的互联网上闲逛,现在尤其是在 angular.io style docs 上,我发现很多对 @HostBinding
和 @HostListener
的引用。看起来它们非常基础,但不幸的是,目前它们的文档有点粗略。
任何人都可以解释一下它们是什么、它们是如何工作的并举例说明它们的用法吗?
你查过这些官方文档了吗?
HostListener - 声明主机侦听器。 Angular 将在宿主元素发出指定事件时调用装饰方法。
@HostListener
- 将监听由 @HostListener
.
HostBinding - 声明主机 属性 绑定。 Angular 在更改检测期间自动检查主机 属性 绑定。如果绑定更改,它将更新指令的主机元素。
@HostBinding
- 将 属性 绑定到宿主元素,如果绑定更改,HostBinding
将更新宿主元素。
注意: 这两个链接最近都已删除。在链接 return 之前,样式指南的“HostBinding-HostListening”部分可能是有用的替代方法。
下面是一个简单的代码示例,可以帮助理解这意味着什么:
DEMO:这是 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;
这是一个基本的悬停示例。
组件模板 属性:
模板
<!-- 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 基本上处理主机元素,比如(一个按钮)监听用户的动作并执行某个功能,比如 alert("Ahoy!") 而 @Hostbinding 则相反。在这里,我们在内部监听该按钮发生的变化(比如当它被点击时 class 发生了什么),我们使用该变化来做其他事情,比如发出特定的颜色。
例子
想想你想在一个组件上制作一个收藏图标的场景,现在你知道你必须知道这个项目是否已经被收藏了 class 改变了,我们需要一个方法确定这一点。这正是 @Hostbinding 的用武之地。
在需要知道用户实际执行了什么操作的地方,@Hostlistening 就派上用场了
帮助我记住他们做什么的快速提示 -
HostBinding('value') myValue;
与 [value]="myValue"
和
HostListener('click') myClick(){ }
与 (click)="myClick()"
HostBinding
和HostListener
写在指令中
其他的 (...)
和 [..]
写在(组件的)模板中。
总结:
@HostBinding
:这个装饰器将class属性绑定到宿主元素的属性。@HostListener
:这个装饰器绑定了一个class方法到宿主元素的一个事件。
示例:
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
class中的color
属性绑定到组件上的style.color
属性。因此,每当更新color
属性 时,组件 的 - 结果将是每当有人单击该组件时颜色就会更新。
style.color
属性 也会更新
在@Directive
中的用法:
虽然它可以用在组件上,但这些装饰器通常用在属性指令中。当在 @Directive
中使用时,主机会更改放置指令的元素。例如看看这个组件模板:
<p p_Dir>some paragraph</p>
这里 p_Dir 是 <p>
元素上的指令。当在指令 class 中使用 @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:动态绑定自定义逻辑到主机元素
@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>