在 Angular 2+ 中构建指令与构建组件没有太大区别。 毕竟,组件只是附加了视图的指令。 实际上,Angular 中存在三种指令:组件、属性指令和结构指令。
结构指令在 DOM 中添加或删除元素。 NgIf、ngFor 和 ngSwitch 是内置结构指令的示例。 属性指令用于更改元素的样式或行为。
让我们通过一个带有 appShadow 指令的示例来学习如何创建自定义属性指令。
定义指令类
从 @angular/core 导入 Directive、ElementRef 和 Renderer2,然后使用渲染器将元素的样式设置为我们想要的 [X163X ]box-shadow 值:
指令:shadow.directive.ts
import { Directive, ElementRef, Renderer2 } from '@angular/core';
请注意我们的选择器是如何用括号括起来的:[appShadow],以使其成为属性指令。
在我们的 app 模块中声明它
以下是在应用根模块中声明我们的新指令的方式:
应用模块:app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { ShadowDirective } from './shadow.directive';
在我们的模板中使用指令
现在就像在我们的模板中使用属性指令一样简单,如下所示:
应用模块:app.component.html
<span appShadow>Alligator</span>
改进我们的指令
我们的 appShadow 指令有点笨,我们可以简单地使用 样式绑定 来应用阴影。 因此,让我们通过允许将值传递给我们的指令来使它变得更好:
指令:shadow.directive.ts
import { Directive, ElementRef, Input, Renderer2, OnInit } from '@angular/core'; @Directive({ selector: '[appShadow]' }) export class ShadowDirective implements OnInit { @Input() appShadow: string; @Input() appShadowX: string; @Input() appShadowY: string; @Input() appShadowBlur: string; constructor(private elem: ElementRef, private renderer: Renderer2) { } ngOnInit() { let shadowStr = `${ this.appShadowX } ${ this.appShadowY } ${ this.appShadowBlur } ${ this.appShadow }`; this.renderer.setStyle(this.elem.nativeElement, 'box-shadow', shadowStr); }
我们使用 inputs 将数据从我们的组件模板传递到指令。 还要注意我们现在如何使用 OnInit 生命周期钩子,而不是在构造函数中进行工作。 那是因为我们的输入在构建时没有任何价值。
您现在可以完全控制阴影:
应用模块:app.component.html
<span [appShadow]="'hotpink'" [appShadowX]="'12px'" [appShadowY]="'6px'" [appShadowBlur]="'30px'">Alligator</span>
👉 我们将指令称为 appShadow,而不是 shadow,因为将自定义指令的范围限定在应用程序中是最佳实践。