手记

创建自定义指令

我们通过使用 @Directive 装饰器来创建自定义指令。

基本结构:

import { Directive } from '@angular/core';

@Directive({
  selector: '[appToolTip]'
})
export class ToolTipDirective {

  constructor() { }

}

注意:selector: ‘[appToolTip]’ 里的 appToolTip 是一个属性选择器,它是用来将指令与HTML元素进行匹配。

构造函数 constructor() { }中,通常会注入两个比较重要的依赖:ElementRef 与 Renderer。
其中,ElementRef 是实际 DOM 元素的包装器,我们可以通过 nativeElement 属性访问实际 DOM 元素。
Renderer 是渲染器,由于 Angular 是跨平台构建应用(Web、移动 Web、移动应用、原生应用和桌面原生应用等),因此 Angular 提供了一套独立于各类平台,用于操作元素的方法。

引入两种依赖:

import { Directive, ElementRef, Renderer2 } from '@angular/core';

@Directive({
  selector: '[appToolTip]'
})
export class ToolTipDirective {

  constructor(
    private el: ElementRef,
    private renderer: Renderer2,
  ) { }

}

接下来,我们创建一个自定义的指令 appToolTip,当鼠标移动到该元素的时候,appToolTip 显示,当鼠标移出该元素的时候,appToolTip 隐藏。

例子:

toolTip.directive.ts

import { Directive, ElementRef, Renderer2, Input, HostListener } from '@angular/core';

@Directive({
  selector: '[appToolTip]'
})
export class ToolTipDirective {

  // Input 装饰器,用来标记输入属性
  @Input() content!: string;
  toolTip: any;

  constructor(
    private el: ElementRef,
    private renderer: Renderer2,
  ) { }

  // HostListener 装饰器,用于声明要监听的 DOM 事件,并提供在该事件发生时要运行的处理器方法。
  @HostListener('mouseenter', ['$event']) 
  onMouseEnter(event: any) {
    if (!this.toolTip) { this.open(); }
  }
 
  @HostListener('mouseleave') 
  onMouseLeave() {
    if (this.toolTip) { this.close(); }
  }

  open(){
    this.toolTip = this.renderer.createElement('span');
    const text = this.renderer.createText(this.content);
    this.renderer.appendChild(this.toolTip, text);
 
    this.renderer.appendChild(document.body, this.toolTip);
    
    let hostPos = this.el.nativeElement.getBoundingClientRect();
    //let tooltipPos= this.toolTip.getBoundingClientRect();
 
    let top = hostPos.bottom + 10 ; 
    let left = hostPos.left;
 
    //this.renderer.addClass(this.toolTip, 'tooltip');
    this.renderer.setStyle(this.toolTip, 'position', 'absolute');
    this.renderer.setStyle(this.toolTip, 'background', 'red');
    this.renderer.setStyle(this.toolTip, 'top', `${top}px`);
    this.renderer.setStyle(this.toolTip, 'left', `${left}px`);
  }

  close(){
    this.renderer.removeClass(this.toolTip, 'tooltip');
    this.renderer.removeChild(document.body, this.toolTip);
    this.toolTip = null;
  }

}

如果需要使用该指令,需要在 Module 中引入指令:

in-payment.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
import { InPaymentRouteModule, Components } from './in-payment.routing.module';
import { MaterialModule } from '@common/material/material.module';
import { InPaymentService } from './service/in-payment.service';
import { PassPaginatorModule } from '@common/material/pass-paginator/pass-paginator.module';

// 引入指令
import { ToolTipDirective } from '@common/service/directive/toolTip.directive';

@NgModule({
  declarations: [
    ...Components,

   // 注入指令
    ToolTipDirective,
  ],
  imports: [
    CommonModule,
    ReactiveFormsModule,
    InPaymentRouteModule,
    MaterialModule,
    PassPaginatorModule,
  ],
  providers: [
    InPaymentService
  ],
})
export class InPaymentModule { }

最后,在该 Module 管辖的模板文件中,就可以使用指令:

in-payment.component.html

<span appToolTip content="国内案件">国内案件</span>
0人推荐
随时随地看视频
慕课网APP