属性型指令
Attribute directives
使用属性型指令,可以更改 DOM 元素和 Angular 组件的外观或行为。
With attribute directives, you can change the appearance or behavior of DOM elements and Angular components.
有关包含本指南中代码片段的有效示例,请参见
See the
建立属性型指令
Building an attribute directive
本节将引导你创建“突出显示”指令,该指令会将宿主元素的背景色设置为黄色。
This section walks you through creating a highlight directive that sets the background color of the host element to yellow.
要创建指令,请使用 CLI 命令
ng generate directive
。To create a directive, use the CLI command
ng generate directive
.ng generate directive highlight
CLI 创建
src/app/highlight.directive.ts
以及相应的测试文件src/app/highlight.directive.spec.ts
,并在AppModule
中声明此指令类。The CLI creates
src/app/highlight.directive.ts
, a corresponding test filesrc/app/highlight.directive.spec.ts
, and declares the directive class in theAppModule
.CLI 生成默认的
src/app/highlight.directive.ts
,如下所示:The CLI generates the default
src/app/highlight.directive.ts
as follows:src/app/highlight.directive.ts import { Directive } from '@angular/core'; @Directive({ selector: '[appHighlight]' }) export class HighlightDirective { constructor() { } }
@Directive()
装饰器的配置属性会指定指令的 CSS 属性选择器[appHighlight]
。The
@Directive()
decorator's configuration property specifies the directive's CSS attribute selector,[appHighlight]
.从
@angular/core
导入ElementRef
。ElementRef
的nativeElement
属性会提供对宿主 DOM 元素的直接访问权限。Import
ElementRef
from@angular/core
.ElementRef
grants direct access to the host DOM element through itsnativeElement
property.在指令的
constructor()
中添加ElementRef
以注入对宿主 DOM 元素的引用,该元素就是appHighlight
的作用目标。Add
ElementRef
in the directive'sconstructor()
to inject a reference to the host DOM element, the element to which you applyappHighlight
.向
HighlightDirective
类中添加逻辑,将背景设置为黄色Add logic to the
HighlightDirective
class that sets the background to yellow.src/app/highlight.directive.ts import { Directive, ElementRef } from '@angular/core'; @Directive({ selector: '[appHighlight]' }) export class HighlightDirective { constructor(el: ElementRef) { el.nativeElement.style.backgroundColor = 'yellow'; } }
指令不支持名称空间。
Directives do not support namespaces.
<p app:Highlight>This is invalid</p>
应用属性型指令
Applying an attribute directive
要使用
HighlightDirective
,请将<p>
元素添加到 HTML 模板中,并以伪指令作为属性。To use the
HighlightDirective
, add a<p>
element to the HTML template with the directive as an attribute.src/app/app.component.html <p appHighlight>Highlight me!</p>
Angualr 会创建 HighlightDirective
类的实例,并将 <p>
元素的引用注入到该指令的构造函数中,它会将 <p>
元素的背景样式设置为黄色。
Angular creates an instance of the HighlightDirective
class and injects a reference to the <p>
element into the directive's constructor, which sets the <p>
element's background style to yellow.
处理用户事件
Handling user events
本节会展示如何检测用户何时将鼠标移入或移出元素以及如何通过设置或清除突出显示颜色来进行响应。
This section shows you how to detect when a user mouses into or out of the element and to respond by setting or clearing the highlight color.
从 '@angular/core' 导入
HostListener
Import
HostListener
from '@angular/core'.src/app/highlight.directive.ts (imports) import { Directive, ElementRef, HostListener } from '@angular/core';
添加两个事件处理程序,它们会在鼠标进入或离开时做出响应,每个事件处理程序都带有
@HostListener()
装饰器。Add two event handlers that respond when the mouse enters or leaves, each with the
@HostListener()
decorator.src/app/highlight.directive.ts (mouse-methods) @HostListener('mouseenter') onMouseEnter() { this.highlight('yellow'); } @HostListener('mouseleave') onMouseLeave() { this.highlight(null); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }
使用
@HostListener()
装饰器,你可以订阅本属性型指令宿主 DOM 元素上的事件(在本例中是<p>
)。With the
@HostListener()
decorator, you can subscribe to events of the DOM element that hosts an attribute directive, the<p>
in this case.处理程序会委托给一个辅助方法
highlight()
,该方法会设置宿主 DOM 元素el
的颜色。The handlers delegate to a helper method,
highlight()
, that sets the color on the host DOM element,el
.
完整的指令如下:
The complete directive is as follows:
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef) { }
@HostListener('mouseenter') onMouseEnter() {
this.highlight('yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
当指针悬停在 p 元素上时,背景颜色就会出现;而当指针移出时,背景颜色就会消失。
The background color appears when the pointer hovers over the paragraph element and disappears as the pointer moves out.
将值传递给属性型指令
Passing values into an attribute directive
本节将引导你在应用 HighlightDirective
时设置突出显示颜色。
This section walks you through setting the highlight color while applying the HighlightDirective
.
在
highlight.directive.ts
中,从@angular/core
导入Input
。In
highlight.directive.ts
, importInput
from@angular/core
.src/app/highlight.directive.ts (imports) import { Directive, ElementRef, HostListener, Input } from '@angular/core';
添加一个
appHighlight
的@Input()
属性。Add an
appHighlight
@Input()
property.src/app/highlight.directive.ts @Input() appHighlight: string;
@Input()
装饰器会将元数据添加到此类,以便让该指令的appHighlight
属性可用于绑定。The
@Input()
decorator adds metadata to the class that makes the directive'sappHighlight
property available for binding.在
app.component.ts
,将color
属性添加到AppComponent
。In
app.component.ts
, add acolor
property to theAppComponent
.src/app/app.component.ts (class) export class AppComponent { color = 'yellow'; }
要同时应用指令和颜色,请通过
appHighlight
指令选择器使用属性绑定,将其设置为color
。To simultaneously apply the directive and the color, use property binding with the
appHighlight
directive selector, setting it equal tocolor
.src/app/app.component.html (color) <p [appHighlight]="color">Highlight me!</p>
[appHighlight]
属性绑定执行两项任务:The
[appHighlight]
attribute binding performs two tasks:将突出显示指令应用于
<p>
元素applies the highlighting directive to the
<p>
element通过属性绑定设置指令的突出显示颜色
sets the directive's highlight color with a property binding
通过用户输入来设置值
Setting the value with user input
本节指导你添加单选按钮,将你选择的颜色绑定到 appHighlight
指令。
This section guides you through adding radio buttons to bind your color choice to the appHighlight
directive.
将标记添加到
app.component.html
以选择颜色,如下所示:Add markup to
app.component.html
for choosing a color as follows:src/app/app.component.html (v2) <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
,使其没有初始值。Revise the
AppComponent.color
so that it has no initial value.src/app/app.component.ts (class) export class AppComponent { color: string; }
启动本应用的开发服务器,以验证用户可以通过单选按钮选择颜色。
Serve your application to verify that the user can choose the color with the radio buttons.
绑定到第二个属性
Binding to a second property
本节将指导你配置应用程序,以便开发人员可以设置默认颜色。
This section guides you through configuring your application so the developer can set the default color.
将第二个
Input()
属性defaultColor
添加到HighlightDirective
。Add a second
Input()
property toHighlightDirective
calleddefaultColor
.src/app/highlight.directive.ts (defaultColor) @Input() defaultColor: string;
修改指令的
onMouseEnter
,使其首先尝试使用highlightColor
进行突出显示,然后尝试defaultColor
,如果两个属性都undefined
,则变回red
。Revise the directive's
onMouseEnter
so that it first tries to highlight with thehighlightColor
, then with thedefaultColor
, and falls back tored
if both properties areundefined
.src/app/highlight.directive.ts (mouse-enter) @HostListener('mouseenter') onMouseEnter() { this.highlight(this.highlightColor || this.defaultColor || 'red'); }
若要绑定到
AppComponent.color
并回退为默认颜色“紫罗兰(violet)”,请添加以下 HTML。在这里,defaultColor
绑定没有使用方括号[]
,因为它是静态的。To bind to the
AppComponent.color
and fall back to "violet" as the default color, add the following HTML. In this case, thedefaultColor
binding doesn't use square brackets,[]
, because it is static.src/app/app.component.html (defaultColor) <p [appHighlight]="color" defaultColor="violet"> Highlight me too! </p>
与组件一样,你可以将指令的多个属性绑定添加到宿主元素上。
As with components, you can add multiple directive property bindings to a host element.
如果没有默认颜色(defaultColor)绑定,则默认为红色。当用户选择一种颜色时,所选的颜色将成为突出显示的颜色。
The default color is red if there is no default color binding. When the user chooses a color the selected color becomes the active highlight color.
通过 NgNonBindable
停用 Angular 处理过程
Deactivating Angular processing with NgNonBindable
要防止在浏览器中进行表达式求值,请将 ngNonBindable
添加到宿主元素。ngNonBindable
会停用模板中的插值、指令和绑定。
To prevent expression evaluation in the browser, add ngNonBindable
to the host element. ngNonBindable
deactivates interpolation, directives, and binding in templates.
在下面的示例中,表达式 {{ 1 + 1 }}
的渲染方式会和在代码编辑器的一样,而不会显示 2
。
In the following example, the expression {{ 1 + 1 }}
renders just as it does in your code editor, and does not display 2
.
<p>Use ngNonBindable to stop evaluation.</p>
<p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p>
将 ngNonBindable
应用于元素将停止对该元素的子元素的绑定。但是,ngNonBindable
仍然允许指令在应用 ngNonBindable
的元素上工作。在以下示例中,appHighlight
指令仍处于活跃状态,但 Angular 不会对表达式 {{ 1 + 1 }}
求值。
Applying ngNonBindable
to an element stops binding for that element's child elements. However, ngNonBindable
still allows directives to work on the element where you apply ngNonBindable
. In the following example, the appHighlight
directive is still active but Angular does not evaluate the expression {{ 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 会禁用该元素的子元素的任何插值和绑定,例如属性绑定或事件绑定。
If you apply ngNonBindable
to a parent element, Angular disables interpolation and binding of any sort, such as property binding or event binding, for the element's children.