angular 内置了不少指令,可是这篇笔记主要记录如何自定义指令。html
- 导入 Directive 装饰器(而再也不是 Component), 指令带有 @Directive 装饰器。
- 导入所需符号 Input、TemplateRef 和 ViewContainerRef, 任何结构型指令都会用到以上三个(属性型经常使用:ElementRef、HostListener)。
- 给指令类添加装饰器。
- 设置 CSS 属性选择器 ,以便在模板中标识出这个指令该应用于哪一个元素。
// 建立指令的 CLI 命令
ng generate directive highlight
复制代码
import { Directive } from '@angular/core';
@Directive({
// 定义一个 CSS 属性型选择器 [appHighlight], 一般带前缀(除ng),如app等,确保它们不会与标准 HTML 属性冲突
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor() { }
}
复制代码
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
// [appHighlight]定义了一个CSS 属性选择器
// 属性名应该拼写成小驼峰形式,而且带有一个前缀,如app。这个前缀不能用 ng,由于它只属于 Angular 自己。
selector: '[appHighlight]'
})
export class HighlightDirective {
// ElementRef 经过其 nativeElement 属性能够直接访问宿主 DOM 元素
constructor(private el: ElementRef) { }
// @Input 的参数中把该选择器highlightColor指定为别名appHighlight。
@Input('appHighlight') highlightColor: string;
// @HostListener 装饰器订阅某个属性型指令所在的宿主 DOM 元素的事件
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || 'red');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
复制代码
<p [appHighlight]="'orange'">Highlighted in orange</p>
复制代码
结构型指令中星号()被放在指令的属性名以前, Angular 会把星号()语法解开成
<ng-template>
app
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({ selector: '[appUnless]'})
export class UnlessDirective {
private hasView = false;
// 使用TemplateRef取得 <ng-template> 的内容,并经过ViewContainerRef来访问这个视图容器
constructor( private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
// 没有人会读取 appUnless 属性,所以它不须要定义 getter。
@Input() set appUnless(condition: boolean) {
if (!condition && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
} else if (condition && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
}
复制代码
<p *appUnless="condition" class="unless a">1111</p>
复制代码