在前几天中有介绍了 Angular 中内建的一些 attribute directive,但是在实际开发专案时可能会遇到内建 attribute directive 无法处理的问题,这时候就需要建立客制化 attribute directive,本章就会介绍如何建立属於自己的 attribute directive。
来跟着 Angular 的官方文档做一个练习,将会建立一个客制化的 attribute directive,将一个宿主 element 的背景颜色设置为黄色的 directive。
首先先使用 Angular CLI 建立一个 directive
ng generate directive highlight
ng g d highlight
使用这个 CLI 指令可以自动建立一个名为 highlight.directive.ts 和 highlight.directive.spec.ts 的档案,并且会在被加入到 app.module.ts 的 declares
,所以如果不是用 CLI 建立 directive file 时,要记得手动将它加入到 declares 里面喔!
在 highlight.directive.ts 中从 @angular/core
中导入 ElementRef
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) { // (1)
el.nativeElement.style.backgroundColor = 'yellow'; // (2)
}
}
nativeElement
property 授与对宿主 DOM element 的直接访问权限,并将他的 style 改变为黄色在 app.component.html 中添加一个 element 并将刚刚客制化的 directive 加在上面
<!-- app.component.html -->
<p appHighlight>Highlight me!</p>
Angular 会将 HighlightDirective 给实例化并将对 <p>
element 的 reference injects 到 highlight.directive.ts 的 constructor 中,让他可以对这个元素的 style 进行更改。
除了改变 element 之外也可以在客制化的 directive 中检测用户在画面中的事件(鼠标移入或移出)并对事件进行不同的响应。
举个例子,保持上面的例子只是将画面上的 <p>
element 绑定一个 hover 事件,当鼠标移到上面时将他背景颜色改为黄色
从 @angular/core
中导入 HostListener
import { Directive, ElementRef, HostListener } from '@angular/core';
更改 highlight.directive.ts 中的 method 用於响应事件
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef) {}
@HostListener('mouseenter') onMouseEnter() { // (1)
this.highlight('yellow');
}
@HostListener('mouseleave') onMouseLeave() { // (2)
this.highlight('');
}
private highlight(color: string) { // (3)
this.el.nativeElement.style.backgroundColor = color;
}
}
在画面中可以看,当我们的鼠标移动到 <p>
element 上面时会触发 highlight.directive.ts 中的 method 将他的背景颜色改为黄色。
除了将你要更改的内容写死在 directive 之外(上面例子是写死 hover 时背景变黄色),你也可以透过传递参数的方式,动态的传递你所期望改变的内容,一样拿上面的例子来延伸吧
首先先改变 highlight.directive.ts 的内容
import { Directive, ElementRef, HostListener, Input } from '@angular/core'; // (1)
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@Input() appHighlight = ''; // (2)
constructor(private el: ElementRef) {}
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.appHighlight); // (3)
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight('');
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
@angular/core
中引入 Input更改 app.component.html 的内容,将颜色传递给 HighlightDirective
<!-- app.component.html -->
<p [appHighlight]="'red'">Highlight me!</p>
可以看到画面中,当鼠标移动到 element 时从黄色变为我们传递给 directive 的红色了。
除了可以传递参数给 directive 之外还可以对他设定一个预设值,以上面例子来说,我们可以设定一个预设值,直到使用者改变颜色後才变为指定的颜色
更改 highlight.directive.ts 中的内容
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@Input() appHighlight = '';
@Input() defaultColor = ''; // (1)
constructor(private el: ElementRef) {}
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.appHighlight || this.defaultColor || 'red');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight('');
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
在 app.component.ts 中添加一个 property 与 method
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
color = ''; // (1)
onClick (color: string) { // (2)
this.color = color;
}
}
在 app.component.html 中新增三个 <button>
并将 directive 加上预设值
<!-- app.component.html -->
<button (click)="onClick('green')">Green</button>
<button (click)="onClick('yellow')">Yellow</button>
<button (click)="onClick('cyan')">Cyan</button>
<p [appHighlight]="color" defaultColor="violet">Highlight me too!</p>
在画面中可以看到,当我们没有点击画面中的 <button>
时我们的鼠标移动到 element 时显示的颜色是预设的颜色,而当点击了其中一个按钮後就换更新为指定的颜色。
本章介绍了如何建立与使用客制化的 directive,可以透过使用 ElementRef 的 nativeElement
property 授与对宿主 DOM element 的直接访问权限,可以使用 HostListener 用来处理画面中使用者的行为,也可以使用之前提到的 @Input() 用於传递参数进到 directive 中,这个客制化的 directive 对於要处理特别的情况时非常好用。
下一章将介绍如何创建客制化的 structural directive并介绍 directive 使如何工作的、 Angular 如解释速记以及如何添加 template 的保护 property 用於捕获 template 的错误,那我们就明天见罗!
>>: @Day15 | C# WixToolset + WPF 帅到不行的安装包 [安装包上的图片]
前言 前面两天刻了两个 view, 现在要用 Navigation 来把它们连接起来。 实作 在 R...
...
职位描述是职位设计的输出之一,它考虑了“分工”的原则,需要人力资源部和研发部进行协作。职位描述是确定...
引言 我们前几天已经把 General Skills 完成了,所以今天开始 (已经没剩几天了 就至...
RegScanner 今天来认识看名字应该是注册表扫描?的小工具.... RegScanner 是可...