在 Angular 中使用自定义组件作为工具提示 [英] Use custom component as tooltip in Angular

查看:24
本文介绍了在 Angular 中使用自定义组件作为工具提示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在 Angular 8 中使用自定义组件作为工具提示?
如果没有直接设置 mat-tooltip 的样式,我想知道是否可以使用自定义组件在使用指令时显示为工具提示.就像显示工具提示时,显示我的组件"一样.
可以吗?

解决方案

是的,您可以创建自定义工具提示指令.

tooltip.directive.ts

import { Directive, Input, ElementRef, HostListener, Renderer2 } from '@angular/core';@指示({选择器:'[工具提示]'})导出类 TooltipDirective {@Input('tooltip') tooltipTitle: 字符串;@Input() 位置:字符串;@Input() 延迟:字符串;工具提示:HTMLElement;偏移= 10;构造函数(私有 el:ElementRef,私有渲染器:Renderer2){}@HostListener('mouseenter') onMouseEnter() {if (!this.tooltip) { this.show();}}@HostListener('mouseleave') onMouseLeave() {if (this.tooltip) { this.hide();}}展示() {this.create();this.setPosition();this.renderer.addClass(this.tooltip, 'ng-tooltip-show');}隐藏() {this.renderer.removeClass(this.tooltip, 'ng-tooltip-show');window.setTimeout(() => {this.renderer.removeChild(document.body, this.tooltip);this.tooltip = null;}, this.delay);}创建() {this.tooltip = this.renderer.createElement('span');this.renderer.appendChild(这个工具提示,this.renderer.createText(this.tooltipTitle)//这是你的文字);this.renderer.appendChild(document.body, this.tooltip);this.renderer.addClass(this.tooltip, 'ng-tooltip');this.renderer.addClass(this.tooltip, `ng-tooltip-${this.placement}`);this.renderer.setStyle(this.tooltip, '-webkit-transition', `opacity ${this.delay}ms`);this.renderer.setStyle(this.tooltip, '-moz-transition', `opacity ${this.delay}ms`);this.renderer.setStyle(this.tooltip, '-o-transition', `opacity ${this.delay}ms`);this.renderer.setStyle(this.tooltip, 'transition', `opacity ${this.delay}ms`);}设置位置(){const hostPos = this.el.nativeElement.getBoundingClientRect();const tooltipPos = this.tooltip.getBoundingClientRect();const scrollPos = window.pageYOffset ||document.documentElement.scrollTop ||document.body.scrollTop ||0;让上,左;if (this.placement === 'top') {top = hostPos.top - tooltipPos.height - this.offset;left = hostPos.left + (hostPos.width - tooltipPos.width)/2;}if (this.placement === '底部') {顶部 = hostPos.bottom + this.offset;left = hostPos.left + (hostPos.width - tooltipPos.width)/2;}if (this.placement === 'left') {top = hostPos.top + (hostPos.height - tooltipPos.height)/2;left = hostPos.left - tooltipPos.width - this.offset;}if (this.placement === 'right') {top = hostPos.top + (hostPos.height - tooltipPos.height)/2;left = hostPos.right + this.offset;}this.renderer.setStyle(this.tooltip, 'top', `${top + scrollPos}px`);this.renderer.setStyle(this.tooltip, 'left', `${left}px`);}}

app.component.ts

import { Component } from '@angular/core';@成分({选择器:'app-root',模板:`<div class="tooltip-example"><div tooltip="左侧描述";位置=左"延迟=500">左侧的提示</div><div tooltip="顶部描述"放置=顶部"延迟=500">顶部的提示</div><div tooltip="底部描述";放置=底部"延迟=500">底部的提示</div><div tooltip="正确的描述";位置=正确"延迟=500">右边的提示</div>

`,样式:[`.tooltip-example {文本对齐:居中;填充:0 50px;}.tooltip-example [工具提示] {显示:内联块;边距:50px 20px;宽度:180px;高度:50px;边框:1px纯灰色;边框半径:5px;行高:50px;文本对齐:居中;}.ng-工具提示{位置:绝对;最大宽度:150px;字体大小:14px;文本对齐:居中;颜色:#f8f8f2;填充:3px 8px;背景:#282a36;边框半径:4px;z-索引:1000;不透明度:0;}.ng-工具提示:{内容:《》;位置:绝对;边框样式:实心;}.ng-tooltip-top:after {顶部:100%;左:50%;左边距:-5px;边框宽度:5px;边框颜色:黑色透明透明透明;}.ng-tooltip-bottom:after {底部:100%;左:50%;左边距:-5px;边框宽度:5px;边框颜色:透明透明黑色透明;}.ng-tooltip-left:after {顶部:50%;左:100%;边距顶部:-5px;边框宽度:5px;border-color:透明透明透明黑色;}.ng-tooltip-right:after {顶部:50%;正确:100%;边距顶部:-5px;边框宽度:5px;边框颜色:透明黑色透明透明;}.ng-工具提示显示{不透明度:1;}`]})导出类 AppComponent {}

app.module.ts

import { BrowserModule } from '@angular/platform-b​​rowser';从'@angular/core' 导入 { NgModule };从 './app.component' 导入 { AppComponent };从 './tooltip.directive' 导入 { TooltipDirective };@NgModule({声明: [应用组件,工具提示指令],进口:[浏览器模块],提供者:[],引导程序:[AppComponent]})导出类 AppModule { }

Is it possible to use a custom component as tooltip in Angular 8?
Without styling directly the mat-tooltip I'm wondering if one can use a custom component to show as tooltip when using the directive. Like "when showing tooltip, show my component".
Can it be done?

解决方案

Yes, You can create your custom tooltip directive.

tooltip.directive.ts

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

@Directive({
  selector: '[tooltip]'
})
export class TooltipDirective {
  @Input('tooltip') tooltipTitle: string;
  @Input() placement: string;
  @Input() delay: string;
  tooltip: HTMLElement;
  offset = 10;

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

  @HostListener('mouseenter') onMouseEnter() {
    if (!this.tooltip) { this.show(); }
  }

  @HostListener('mouseleave') onMouseLeave() {
    if (this.tooltip) { this.hide(); }
  }

  show() {
    this.create();
    this.setPosition();
    this.renderer.addClass(this.tooltip, 'ng-tooltip-show');
  }

  hide() {
    this.renderer.removeClass(this.tooltip, 'ng-tooltip-show');
    window.setTimeout(() => {
      this.renderer.removeChild(document.body, this.tooltip);
      this.tooltip = null;
    }, this.delay);
  }

  create() {
    this.tooltip = this.renderer.createElement('span');

    this.renderer.appendChild(
      this.tooltip,
      this.renderer.createText(this.tooltipTitle) // Here is your text
    );

    this.renderer.appendChild(document.body, this.tooltip);

    this.renderer.addClass(this.tooltip, 'ng-tooltip');
    this.renderer.addClass(this.tooltip, `ng-tooltip-${this.placement}`);
    this.renderer.setStyle(this.tooltip, '-webkit-transition', `opacity ${this.delay}ms`);
    this.renderer.setStyle(this.tooltip, '-moz-transition', `opacity ${this.delay}ms`);
    this.renderer.setStyle(this.tooltip, '-o-transition', `opacity ${this.delay}ms`);
    this.renderer.setStyle(this.tooltip, 'transition', `opacity ${this.delay}ms`);
  }

  setPosition() {
    const hostPos = this.el.nativeElement.getBoundingClientRect();
    const tooltipPos = this.tooltip.getBoundingClientRect();

    const scrollPos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;

    let top, left;

    if (this.placement === 'top') {
      top = hostPos.top - tooltipPos.height - this.offset;
      left = hostPos.left + (hostPos.width - tooltipPos.width) / 2;
    }

    if (this.placement === 'bottom') {
      top = hostPos.bottom + this.offset;
      left = hostPos.left + (hostPos.width - tooltipPos.width) / 2;
    }

    if (this.placement === 'left') {
      top = hostPos.top + (hostPos.height - tooltipPos.height) / 2;
      left = hostPos.left - tooltipPos.width - this.offset;
    }

    if (this.placement === 'right') {
      top = hostPos.top + (hostPos.height - tooltipPos.height) / 2;
      left = hostPos.right + this.offset;
    }

    this.renderer.setStyle(this.tooltip, 'top', `${top + scrollPos}px`);
    this.renderer.setStyle(this.tooltip, 'left', `${left}px`);
  }
}

app.component.ts

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

@Component({
  selector: 'app-root',
  template: `
    <div class="tooltip-example">
      <div tooltip="left description" placement="left" delay="500">tootip on left</div>
      <div tooltip="top description" placement="top" delay="500">tootip on top</div>
      <div tooltip="bottom description" placement="bottom" delay="500">tootip on bottom</div>
      <div tooltip="right description" placement="right" delay="500">tootip on right</div>
    </div>
  `,
  styles: [`
    .tooltip-example {
      text-align: center;
      padding: 0 50px;
    }
    .tooltip-example [tooltip] {
      display: inline-block;
      margin: 50px 20px;
      width: 180px;
      height: 50px;
      border: 1px solid gray;
      border-radius: 5px;
      line-height: 50px;
      text-align: center;
    }
    .ng-tooltip {
      position: absolute;
      max-width: 150px;
      font-size: 14px;
      text-align: center;
      color: #f8f8f2;
      padding: 3px 8px;
      background: #282a36;
      border-radius: 4px;
      z-index: 1000;
      opacity: 0;
    }
    .ng-tooltip:after {
      content: "";
      position: absolute;
      border-style: solid;
    }
    .ng-tooltip-top:after {
      top: 100%;
      left: 50%;
      margin-left: -5px;
      border-width: 5px;
      border-color: black transparent transparent transparent;
    }
    .ng-tooltip-bottom:after {
      bottom: 100%;
      left: 50%;
      margin-left: -5px;
      border-width: 5px;
      border-color: transparent transparent black transparent;
    }
    .ng-tooltip-left:after {
      top: 50%;
      left: 100%;
      margin-top: -5px;
      border-width: 5px;
      border-color: transparent transparent transparent black;
    }
    .ng-tooltip-right:after {
      top: 50%;
      right: 100%;
      margin-top: -5px;
      border-width: 5px;
      border-color: transparent black transparent transparent;
    }
    .ng-tooltip-show {
      opacity: 1;
    }
  `]
})
export class AppComponent {}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { TooltipDirective } from './tooltip.directive';

@NgModule({
  declarations: [
    AppComponent,
    TooltipDirective
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

这篇关于在 Angular 中使用自定义组件作为工具提示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆