hao同学的技术博客

  • 首页
  • Java
    • Java
    • JVM教程
    • Java面试
    • Java并发入门
    • Java并发进阶
  • 项目
    • 从零打造项目
  • Python
    • Python
    • Python爬虫
    • 算法
  • Java框架
    • Spring
    • SpringBoot
  • 前端
    • Angular
  • 其他
    • Linux
    • SQL
  • 随笔
分享技术,记录人生
一个痴迷于技术的厨艺爱好者
  1. 首页
  2. Angular
  3. 正文

Angular之属性型指令学习

2022年5月28日 405点热度 0人点赞 0条评论

Angular之属性型指令学习插图

在 Angular 中有三种类型的指令:

  1. 组件 — 拥有模板的指令
  2. 结构型指令 — 通过添加和移除 DOM 元素改变 DOM 布局的指令
  3. 属性型指令 — 改变元素、组件或其它指令的外观和行为的指令。

组件是这三种指令中最常用的。 你在快速上手例子中第一次见到组件。

结构型指令修改视图的结构。例如,NgFor 和 NgIf。 要了解更多,参见结构型指令 guide。

属性型指令改变一个元素的外观或行为。例如,内置的 NgStyle 指令可以同时修改元素的多个样式。

创建一个简单的属性型指令

在命令行窗口下用 CLI 命令 ng generate directive 创建指令类文件。

ng g directive components3/highlight

CLI 会创建 src/app/components3/highlight.directive.ts 及相应的测试文件(src/app/components3/highlight.directive.spec.ts),并且在根模块 AppModule 中声明这个指令类。

生成的 highlight.directive.ts 文件如下:

import { Directive } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  constructor() { }

}

修改该文件,内容如下:

import { Directive, ElementRef } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  constructor(public el: ElementRef) {
    el.nativeElement.style.backgroundColor = 'yellow';
  }

}

使用属性型指令

在 home3.component.html 文件中使用定义的属性型指令。

<p appHighlight>Highlight me!</p>

实际效果如下:

Angular之属性型指令学习插图1

响应用户引发的事件

上述案例中 appHighlight 只是简单的设置元素的颜色。接下来我们希望这个指令能够实现这么一个功能:在用户鼠标悬浮一个元素时,设置它的颜色。

修改 highlight.directive.ts 文件如下:

import { Directive, ElementRef,HostListener } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  //鼠标进入做出响应
  @HostListener('mouseenter') onMouseEnter(){
    this.highlight('yellow');
  }

  //鼠标离开做出响应
  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  constructor(public el: ElementRef) {
  }

  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}

实际效果为:

Angular之属性型指令学习插图2

当把鼠标移到 p 上的时候,背景色就出现了,而移开时就消失了。

使用 @Input 数据绑定向指令传递值

上述的案例只是满足了用户最简单的一个需求,但是这不够灵活,用户希望能够指定选择哪种颜色进行高亮。

此时我们的 highlight.directive.ts 文件需要另外引入 Input,如下:

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  @Input() highlightColor: string;

  constructor(public el: ElementRef) {
  }

  // 鼠标进入做出响应
  @HostListener('mouseenter') onMouseEnter() {
    this.highlight(this.highlightColor || 'red');
  }

  // 鼠标离开做出响应
  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}

把 home3.component.ts 改成这样:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home3',
  templateUrl: '
    <h1>My First Attribute Directive</h1>

    <h4>Pick a highlight color</h4>
    <div>
      <input type="radio" name="colors" (click)="color='lightgreen'">Green
      <input type="radio" name="colors" (click)="color='yellow'">Yellow
      <input type="radio" name="colors" (click)="color='cyan'">Cyan
    </div>
    <p appHighlight [highlightColor]="color">Highlight me!</p>
  '
})
export class Home3Component implements OnInit {

  color: string;
  constructor() { }

  ngOnInit(): void {
  }

}

但是我们发现下列指令绑定变量的写法有点复杂。

<p appHighlight [highlightColor]="color">Highlight me!</p>

如果可以在应用该指令时在同一个属性中设置颜色就更好了,就像这样:

<p [appHighlight]="color">Highlight me!</p>

[appHighlight] 属性同时做了两件事:把这个高亮指令应用到了

元素上,并且通过属性绑定设置了该指令的高亮颜色。 你复用了该指令的属性选择器 [appHighlight] 来同时完成它们。 这是清爽、简约的语法。

在 @Input 的参数中把该选择器指定为别名。

@Input('appHighlight') highlightColor: string;

在指令内部,该属性叫 highlightColor,在外部,你绑定到它地方,它叫 appHighlight。

最终修改完毕后,页面实际效果如下:

Angular之属性型指令学习插图3

绑定到第二个属性

上述案例的指令只有一个可定制属性,真实的应用通常需要更多。

目前,默认颜色(它在用户选取了高亮颜色之前一直有效)被硬编码为红色。应该允许模板的开发者设置默认颜色。

把第二个名叫 defaultColor 的输入属性添加到 HighlightDirective 中:

此时我们的 highlight.directive.ts 文件如下:

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  @Input('appHighlight') highlightColor: string;
  @Input() defaultColor: string;

  constructor(public el: ElementRef) {
  }

  // 鼠标进入做出响应
  @HostListener('mouseenter') onMouseEnter() {
    this.highlight(this.highlightColor || this.defaultColor || 'red');
  }

  // 鼠标离开做出响应
  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}

把 home3.component.ts 改成这样:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-home3',
  templateUrl: '
    <h1>My First Attribute Directive</h1>

    <h4>Pick a highlight color</h4>
    <div>
      <input type="radio" name="colors" (click)="color='lightgreen'">Green
      <input type="radio" name="colors" (click)="color='yellow'">Yellow
      <input type="radio" name="colors" (click)="color='cyan'">Cyan
    </div>
    <p  [appHighlight]="color">Highlight me!</p>

    <h4>defaultColor is violet</h4>
    <p  [appHighlight]="color" defaultColor="violet">Highlight me too!</p>
  '
})
export class Home3Component implements OnInit {

  color: string;
  constructor() { }

  ngOnInit(): void {
  }

}

Angular 之所以知道 defaultColor 绑定属于 HighlightDirective,是因为你已经通过 @Input 装饰器把它设置成了公共属性。

页面实际效果:

Angular之属性型指令学习插图4

参考文献

官方文档

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: Angular 前端
最后更新:2022年5月28日

hresh

这是一个专注于IT技术学习交流的个人技术博客网站,包括Java学习、Python爬虫、Web开发实践等领域,深耕Java领域,内容涵盖Java基础、Java并发编程、Java虚拟机、Java面试等核心知识点。

点赞
< 上一篇
下一篇 >

文章评论

取消回复

hresh

这是一个专注于IT技术学习交流的个人技术博客网站,包括Java学习、Python爬虫、Web开发实践等领域,深耕Java领域,内容涵盖Java基础、Java并发编程、Java虚拟机、Java面试等核心知识点。

文章目录
  • 创建一个简单的属性型指令
  • 使用属性型指令
  • 响应用户引发的事件
  • 使用 @Input 数据绑定向指令传递值
  • 绑定到第二个属性
  • 参考文献
最新 热点 随机
最新 热点 随机
后端必知:遵循Google Java规范并引入checkstyle检查 Spring Security结合Redis实现缓存功能 Spring Security结合JWT实现认证与授权 Spring Security自定义认证逻辑实现图片验证码登录 Spring Security进阶学习 Spring Security入门学习
GraphicsMagick之实践出真知 Scrapy 爬取今日头条街拍图片 Java面试准备之并发基础 你知道为什么要有两个 Survivor吗?关于卡表技术又有多少了解 关于即时编译器的那些事 Spring bean之间的关系

COPYRIGHT © 2022 hao同学的技术博客. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

鄂ICP备2022007381号

鄂公网安备 42010302002449号