深入了解Angular中的HostBinding和HostListener装饰器


本文摘自PHP中文网,作者青灯夜游,侵删。

本篇文章带大家了解一下Angular中的两个装饰器――HostBinding和HostListener,介绍一下这两个装饰器的使用场景。

我的疑惑

不知道各位小伙伴在自学angular的时候有没有遇到过这两个装饰器――HostBindingHostListener。这两个装饰器我在看官网的api说明的时候,真是百思不得其解,明明每个字我都能看懂,但是连在一起我就是看不懂了。而且官网上面给出的示例也很迷,让我搞不明白这俩api的使用场景到底是啥。【相关教程推荐:《angular教程》】

官网说明

先看看这两个api在官网上面的说明吧:

HostBinding(官网链接):

用于把一个 DOM 属性标记为绑定到宿主的属性,并提供配置元数据。 Angular 在变更检测期间会自动检查宿主属性绑定,如果这个绑定变化了,它就会更新该指令所在的宿主元素。

HostListener(官网链接):

用于声明要监听的 DOM 事件,并提供在该事件发生时要运行的处理器方法。

是不是看完之后也不知道这俩兄弟的使用场景到底是啥?在我看来,这俩装饰器的作用是为了方便我们将复杂的DOM操作可以抽取成一个指令,以此来精简代码。废话不多说,上代码,一看就懂。

代码示例

假设此时有一个业务场景,有一个输入框input,我们每次输入的时候,字的颜色和边框的颜色就会变化一下,我们取名叫“彩虹输入框”。

如果我们不使用组件封装的方式的话,直接在组件中写相关的DOM操作,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

@Component({

  selector: 'app-rainbow-input-demo',

  template: `

    <h3>这是一个彩虹输入框,每输入一次都会改变颜色</h3>

    <input [class]="'my-input'"

           type="text"

           [style]="inputStyleObj"

           (keydown)="onKeyDown()"

    />

  `,

  styles:[

    `.my-input {

        border:none;

        outline: none;

        border: 2px solid #333333;

        border-radius: 5px;

      }`

  ]

})

export class RainbowInputDemoComponent {

  //默认的颜色样式

  public inputStyleObj = {

    color:null,

    borderColor:null,

  };

  //颜色库

  public possibleColors = [

    'darksalmon', 'hotpink', 'lightskyblue',

    'goldenrod', 'peachpuff', 'mediumspringgreen',

    'cornflowerblue', 'blanchedalmond', 'lightslategrey'

  ];

  //键盘落下事件

  onKeyDown(){

    const index = Math.floor(Math.random() * this.possibleColors.length);

    //如果我们直接使用this.inputStyleObj.color = this.possibleColors[index]的话,

    //this.inputStyleObj虽然内容变了,由于它是引用类型,其地址值没有变。所以不会触发视图的重新渲染

    //在angular中,和react似的,我们直接修改引用类型不会触发重新渲染,只能覆盖它或者合并它,使其地址值发生改变,才会触发重新渲染

    //如果觉得麻烦的话,完全可以在模板中使用[style.color]和[style.borderColor]

    this.inputStyleObj = {

      color:this.possibleColors[index],

      borderColor:this.possibleColors[index],

    }

  }

}

效果如图:

1.gif

就这样,我们实现了这个功能,那么现在有个问题。假如这种rainbowInput我们还需要在其他组件用到怎么办,难道每次使用的时候我们都把这些代码复制粘贴一遍吗?很明显这不符合组件封装的原则,如果你真的这么做,技术经理或者项目经理也会打爆你的狗头、

那么我们就需要将其封装成一个组件或者一个指令。在这篇文章中我们先把它封装成一个指令,至于原因后面再说。代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

@Directive({

  selector: '[appRainbow]'

})

export class RainbowInputDirective {

  public possibleColors = [

    'darksalmon', 'hotpink', 'lightskyblue',

    'goldenrod', 'peachpuff', 'mediumspringgreen',

    'cornflowerblue', 'blanchedalmond', 'lightslategrey'

  ];

  //字体颜色

  @HostBinding('style.color') color: string;

  //边框颜色

  @HostBinding('style.borderColor') borderColor: string;

  //监听键盘落下的事件

  @HostListener('keydown') onKeyDown() {

    //获取一个随机的颜色

    const index = Math.floor(Math.random() * this.possibleColors.length);

    this.color = this.borderColor = this.possibleColors[index];

  }

}

 

@Component({

  selector: 'app-rainbow-input-demo',

  template: `

    <h3>这是一个彩虹输入框,每输入一次都会改变颜色</h3>

    <input [class]="'my-input'" type="text" appRainbow />

  `,

  styles:[

    //省略,和上面相同

  ]

})

export class RainbowInputDemoComponent {}

就像上面代码写的那样,我们将重复的逻辑抽取了出来,使代码的维护性和美观度都有了很大的提升。

结论

在代码中我们可以看到@HostBinding的作用其实就是将某个属性绑定到了宿主元素上,但是这个属性不是随随便便的属性。这个属性指的是angular模板中支持的属性,其实@HostBinding就相当于模板中的[]或者bind-。同理@HostListener就相当于模板中的()或者on-。使我们可以在指令当中就可以将属性和方法绑定到宿主元素上,实现的效果和我们第一种直接将(keydow)[style]直接写在模板上是一样的。所以说,这俩装饰器里面的字符串那可不能随便写。

关于指令和组件

但是,其实在angular当中,组件和指令其实区别不是特别大,因为angular中的组件装饰器@Component就是继承自@Directive的。

其实我们将这个DOM操作封装成一个组件也不是不可以,代码如下

1

2

3

@Component({

  selector:'input[appRainbow]'

})

但是和指令写法:

1

2

3

@Directive({

  selector: '[appRainbow]'

})

真的差别不大。

总结

@HostBinding相当于模板上的[]或者bind-

@HostListener相当于模板上的()或者on-

就是angular为了不希望我们直接操作DOM,提供的指令中的数据和方法绑定。

更多编程相关知识,请访问:编程教学!!

以上就是深入了解Angular中的HostBinding和HostListener装饰器的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

浅谈Angular中elem.scope()、elem.isolatescope和$compile(elem)(scope)中scope的区别

Angular中什么是ivy编译?如何开启ivy编译?

浅析Angular路由中的懒加载、守卫、动态参数

2021年值得尝试的7个Angular前端组件库,快来收藏吧!

Angular7中如何引用ng zorro antd?

20个优秀的Angular开源项目,你了解几个呢?

浅谈Angular中父子组件相互传参的方法

详解Angular使用controlvalueaccessor实现自定义表单控件

浅谈Angular中插槽的用法

解决Angular中的浏览器兼容性问题的方法介绍

更多相关阅读请进入《Angular》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...