阅读(3251) (0)

Angular 属性型指令

2022-06-28 10:45:17 更新

属性型指令

使用属性型指令,可以更改 DOM 元素和 Angular 组件的外观或行为。

有关包含本指南中代码片段的有效示例,请参见现场演练 / 下载范例

建立属性型指令

本节将引导你创建“突出显示”指令,该指令会将宿主元素的背景色设置为黄色。

  1. 要创建指令,请使用 CLI 命令 ​ng generate directive​。
  2. 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]​。

  3. 从 ​@angular/core​ 导入 ​ElementRef​。​ElementRef ​的 ​nativeElement ​属性会提供对宿主 DOM 元素的直接访问权限。
  4. 在指令的 ​constructor()​ 中添加 ​ElementRef ​以注入对宿主 DOM 元素的引用,该元素就是 ​appHighlight ​的作用目标。
  5. 向 ​HighlightDirective ​类中添加逻辑,将背景设置为黄色
  6. 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>

应用属性型指令

  1. 要使用 ​HighlightDirective​,请将 ​<p>​ 元素添加到 HTML 模板中,并以伪指令作为属性。
  2. <p appHighlight>Highlight me!</p>

Angualr 会创建 ​HighlightDirective ​类的实例,并将 ​<p>​ 元素的引用注入到该指令的构造函数中,它会将 ​<p>​ 元素的背景样式设置为黄色。

处理用户事件

本节会展示如何检测用户何时将鼠标移入或移出元素以及如何通过设置或清除突出显示颜色来进行响应。

  1. 从 '@angular/core' 导入 ​HostListener
  2. import { Directive, ElementRef, HostListener } from '@angular/core';
  3. 添加两个事件处理程序,它们会在鼠标进入或离开时做出响应,每个事件处理程序都带有 ​@HostListener()​ 装饰器。
  4. @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 ​时设置突出显示颜色。

  1. 在 ​highlight.directive.ts​ 中,从 ​@angular/core​ 导入 ​Input​。
  2. import { Directive, ElementRef, HostListener, Input } from '@angular/core';
  3. 添加一个 ​appHighlight ​的 ​@Input()​ 属性。
  4. @Input() appHighlight = '';

    @Input()​ 装饰器会将元数据添加到此类,以便让该指令的 ​appHighlight ​属性可用于绑定。

  5. 在 ​app.component.ts​,将 ​color ​属性添加到 ​AppComponent​。
  6. export class AppComponent {
      color = 'yellow';
    }
  7. 要同时应用指令和颜色,请通过 ​appHighlight ​指令选择器使用属性绑定,将其设置为 ​color​。
  8. <p [appHighlight]="color">Highlight me!</p>

    [appHighlight]​ 属性绑定执行两项任务:

    • 将突出显示指令应用于 ​<p>​ 元素
    • 通过属性绑定设置指令的突出显示颜色

通过用户输入来设置值

本节指导你添加单选按钮,将你选择的颜色绑定到 ​appHighlight ​指令。

  1. 将标记添加到 ​app.component.html​ 以选择颜色,如下所示:
  2. <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>
  3. 修改 ​AppComponent.color​,使其没有初始值。
  4. export class AppComponent {
      color = '';
    }
  5. 启动本应用的开发服务器,以验证用户可以通过单选按钮选择颜色。

绑定到第二个属性

本节将指导你配置应用程序,以便开发人员可以设置默认颜色。

  1. 将第二个 ​Input()​ 属性 ​defaultColor ​添加到 ​HighlightDirective​。
  2. @Input() defaultColor = '';
  3. 修改指令的 ​onMouseEnter​,使其首先尝试使用 ​highlightColor ​进行突出显示,然后尝试 ​defaultColor​,如果两个属性都 ​undefined​,则变回 ​red​。
  4. @HostListener('mouseenter') onMouseEnter() {
      this.highlight(this.highlightColor || this.defaultColor || 'red');
    }
  5. 若要绑定到 ​AppComponent.color​ 并回退为默认颜色“紫罗兰(violet)”,请添加以下 HTML。在这里,​defaultColor ​绑定没有使用方括号 ​[]​,因为它是静态的。
  6. <p [appHighlight]="color" defaultColor="violet">
      Highlight me too!
    </p>

    与组件一样,你可以将指令的多个属性绑定添加到宿主元素上。

如果没有默认颜色(defaultColor)绑定,则默认为红色。当用户选择一种颜色时,所选的颜色将成为突出显示的颜色。


通过 NgNonBindable 停用 Angular 处理过程

要防止在浏览器中进行表达式求值,请将 ​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 会禁用该元素的子元素的任何插值和绑定,例如属性绑定或事件绑定。