使用属性型指令,可以更改 DOM 元素和 Angular 组件的外观或行为。
有关包含本指南中代码片段的有效示例,请参见现场演练/ 下载范例
本节将引导你创建“突出显示”指令,该指令会将宿主元素的背景色设置为黄色。
ng generate directive
。ng generate directive highlight
CLI 创建 src/app/highlight.directive.ts
以及相应的测试文件 src/app/highlight.directive.spec.ts
,并在 AppModule
中声明此指令类。
CLI 生成默认的 src/app/highlight.directive.ts
,如下所示:
import { Directive } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor() { }
}
@Directive()
装饰器的配置属性会指定指令的 CSS 属性选择器 [appHighlight]
。
@angular/core
导入 ElementRef
。ElementRef
的 nativeElement
属性会提供对宿主 DOM 元素的直接访问权限。 在指令的 constructor()
中添加 ElementRef
以注入对宿主 DOM 元素的引用,该元素就是 appHighlight
的作用目标。 向 HighlightDirective
类中添加逻辑,将背景设置为黄色 import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
指令不支持名称空间。
<p app:Highlight>This is invalid</p>
HighlightDirective
,请将 <p>
元素添加到 HTML 模板中,并以伪指令作为属性。<p appHighlight>Highlight me!</p>
Angualr 会创建 HighlightDirective
类的实例,并将 <p>
元素的引用注入到该指令的构造函数中,它会将 <p>
元素的背景样式设置为黄色。
本节会展示如何检测用户何时将鼠标移入或移出元素以及如何通过设置或清除突出显示颜色来进行响应。
HostListener
import { Directive, ElementRef, HostListener } from '@angular/core';添加两个事件处理程序,它们会在鼠标进入或离开时做出响应,每个事件处理程序都带有
@HostListener()
装饰器。 @HostListener('mouseenter') onMouseEnter() {
this.highlight('yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight('');
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
要订阅本属性型指令宿主 DOM 元素上的事件(在本例中是 <p>
),可以使用 @HostListener()
装饰器。
处理程序会委托给一个辅助方法 highlight()
,该方法会设置宿主 DOM 元素 el
的颜色。
完整的指令如下:
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef) { }
@HostListener('mouseenter') onMouseEnter() {
this.highlight('yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight('');
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
当指针悬停在 p 元素上时,背景颜色就会出现;而当指针移出时,背景颜色就会消失。
本节将引导你在应用 HighlightDirective
时设置突出显示颜色。
highlight.directive.ts
中,从 @angular/core
导入 Input
。import { Directive, ElementRef, HostListener, Input } from '@angular/core';添加一个
appHighlight
的 @Input()
属性。 @Input() appHighlight = '';
@Input()
装饰器会将元数据添加到此类,以便让该指令的 appHighlight
属性可用于绑定。
app.component.ts
,将 color
属性添加到 AppComponent
。 export class AppComponent {要同时应用指令和颜色,请通过
color = 'yellow';
}
appHighlight
指令选择器使用属性绑定,将其设置为 color
。 <p [appHighlight]="color">Highlight me!</p>
[appHighlight]
属性绑定执行两项任务:
<p>
元素本节指导你添加单选按钮,将你选择的颜色绑定到 appHighlight
指令。
app.component.html
以选择颜色,如下所示:<h1>My First Attribute Directive</h1>修改
<h2>Pick a highlight color</h2>
<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>
AppComponent.color
,使其没有初始值。 export class AppComponent {启动本应用的开发服务器,以验证用户可以通过单选按钮选择颜色。
color = '';
}
本节将指导你配置应用程序,以便开发人员可以设置默认颜色。
Input()
属性 defaultColor
添加到 HighlightDirective
。@Input() defaultColor = '';修改指令的
onMouseEnter
,使其首先尝试使用 highlightColor
进行突出显示,然后尝试 defaultColor
,如果两个属性都 undefined
,则变回 red
。 @HostListener('mouseenter') onMouseEnter() {若要绑定到
this.highlight(this.highlightColor || this.defaultColor || 'red');
}
AppComponent.color
并回退为默认颜色“紫罗兰(violet)”,请添加以下 HTML。在这里,defaultColor
绑定没有使用方括号 []
,因为它是静态的。 <p [appHighlight]="color" defaultColor="violet">
Highlight me too!
</p>
与组件一样,你可以将指令的多个属性绑定添加到宿主元素上。
如果没有默认颜色(defaultColor)绑定,则默认为红色。当用户选择一种颜色时,所选的颜色将成为突出显示的颜色。
要防止在浏览器中进行表达式求值,请将 ngNonBindable
添加到宿主元素。ngNonBindable
会停用模板中的插值、指令和绑定。
在下面的示例中,表达式 {{ 1 + 1 }}
的渲染方式会和在代码编辑器的一样,而不会显示 2
。
<p>Use ngNonBindable to stop evaluation.</p>
<p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p>
将 ngNonBindable
应用于元素将停止对该元素的子元素的绑定。但是,ngNonBindable
仍然允许指令在应用 ngNonBindable
的元素上工作。在以下示例中,appHighlight
指令仍处于活跃状态,但 Angular 不会对表达式 {{ 1 + 1 }}
求值。
<h3>ngNonBindable with a directive</h3>
<div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.
</div>
如果将 ngNonBindable
应用于父元素,则 Angular 会禁用该元素的子元素的任何插值和绑定,例如属性绑定或事件绑定。