属性型指令
- 用于改变一个DOM元素的外观或行为。例如,内置的NgStyle指令可以同时修改元素的多个样式。
创建属性型指令
import { Directive, ElementRef, Input, Renderer } from '@angular/core';
@Directive({ selector: '[myHighlight]' })
export class HighlightDirective {
constructor(el: ElementRef, renderer: Renderer) {
renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'yellow');
}
}
- Directive 提供@Directive装饰器功能
- ElementRef 注入到指令构造函数中,使代码可以访问DOM元素。
- Input 就是将数据从绑定表达式传到指令中。
- Renderer 让代码可以改变DOM元素的样式。
- HighlightDirective是指令的控制器类,包括了指令的工作逻辑
PS:属性指令的@Directive装饰器需要一个CSS选择器,以便从模板中识别出关联到这个指令的HTML,CSS 中的attribute选择器就是属性名称加方括号,如例子中的[myHighlight].
- Angular 会为每个匹配的元素创建一个指令控制器类的实例,并把 Angular 的ElementRef和Renderer注入进构造函数。 ElementRef是一个服务,它赋予我们通过它的nativeElement属性直接访问 DOM 元素的能力。 Renderer服务允许通过代码设置元素的样式。
属性型指令的应用
<h1>My First Attribute Directive</h1>
<p myHighlight>Highlight me!</p>
- Angular在
<p>
元素上发现了一个myHighlight属性。然后它创建了一个HighlightDirective类的实例,并把所在元素的引用注入到了指令的构造函数。在构造函数中把<p>
标签的背景设置为黄色。当然,我们首先要在app.module.ts中引入并注册我们的指令。
响应用户引发事件
import { Directive, ElementRef, HostListener, Input, Renderer } from '@angular/core';
@Directive({
selector: '[myHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer) { }
@HostListener('mouseenter') onMouseEnter() {
this.highlight('yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.renderer.setElementStyle(this.el.nativeElement, 'backgroundColor', color);
}
}
- @HostListener装饰器引用属性型指令的宿主元素,在这个例子中就是
<p>
这里把属性的处理逻辑委托给了一个辅助方法,这个方法会通过一个私有变量el来设置颜色,我们要修改构造函数,把ElementRef.nativeElement存进这个私有变量。
使用数据绑定向指令传递值
- 上面我们看到的高亮颜色使我们在指令中硬编码进去的,这种方式让我们的指令变得没有弹性,因此我们并不提倡这种用法,我们可以给支另类增加一个可绑定的输入属性highlightColor,用它来高亮文本。
export class HighlightDirective {
private _defaultColor = 'red';
constructor(private el: ElementRef, private renderer: Renderer) { }
/** 增加一个可绑定的输入型指令*/
@Input('myHighlight') highlightColor: string;
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || this._defaultColor);
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.renderer.setElementStyle(this.el.nativeElement, 'backgroundColor', color);
}
}
<p [myHighlight]="color">Highlight me!</p>
- 代码绑定到myHighlight属性名,但是指令属性名为highlightColor.
绑定第二个属性
- 我们想要设置一个默认颜色,指导用户选择了一个高亮颜色才会失效,就需要给HighlightDirective添加第二个输入型属性defaultColor. 这里我们可以在指令中直接通过set来实现。
@Input() set defaultColor(colorName: string){
this._defaultColor = colorName || this._defaultColor;
}
<p [myHighlight]="color" [defaultColor]="'violet'">
Highlight me too!
</p>
- 我们像以前一样把用户选择的颜色绑定到了myHighlight上。 我们还把字符串字面量'violet'绑定到了defaultColor上。