在 Angular 中使用 Tippy.js
Use Tippy.js in Angular
我有一个包含以下代码的指令
import { Directive, Input, OnInit, ElementRef, SimpleChanges, OnChanges } from '@angular/core';
import tippy from 'tippy.js';
@Directive({
selector: '[tippy]'
})
export class TippyDirective implements OnInit, OnChanges {
@Input('tippyOptions') public tippyOptions: Object;
private el: any;
private tippy: any = null;
private popper: any = null;
constructor(el: ElementRef) {
this.el = el;
}
public ngOnInit() {
this.loadTippy();
}
public ngOnChanges(changes: SimpleChanges) {
if (changes.tippyOptions) {
this.tippyOptions = changes.tippyOptions.currentValue;
this.loadTippy();
}
}
public tippyClose() {
this.loadTippy();
}
private loadTippy() {
setTimeout(() => {
let el = this.el.nativeElement;
let tippyOptions = this.tippyOptions || {};
if (this.tippy) {
this.tippy.destroyAll(this.popper);
}
this.tippy = tippy(el, tippyOptions, true);
this.popper = this.tippy.getPopperElement(el);
});
}
}
并使用指令如下
<input tippy [tippyOptions]="{
arrow: true,
createPopperInstanceOnInit: true
}" class="search-input" type="text"
(keyup)="searchInputKeyDown($event)">
如何在 mouseenter 或 focus 上显示 Tippy,因为这些是默认触发器,从我在指令中的 tippy 实例,这是我在第 44 行 console.log(this.tippy)
时得到的结果
{
destroyAll:ƒ destroyAll()
options:{placement: "top", livePlacement: true, trigger: "mouseenter focus", animation: "shift-away", html: false, …}
selector:input.search-input
tooltips:[]
}
当我尝试使用时出现错误
this.popper = this.tippy.getPopperElement(el);
ERROR TypeError: _this.tippy.getPopperElement is not a function
如何让这个指令生效,因为我是从 github
的仓库中获取它的
https://github.com/tdanielcox/ngx-tippy/blob/master/lib/tippy.directive.ts
我在这里缺少什么,感谢任何帮助,谢谢
我不确定他们在您包含的链接回购中试图完成什么。要使 tippy.js
正常工作,您应该能够将指令更改为以下内容:
import { Directive, Input, OnInit, ElementRef } from '@angular/core';
import tippy from 'tippy.js';
@Directive({
/* tslint:disable-next-line */
selector: '[tippy]'
})
export class TippyDirective implements OnInit {
@Input('tippyOptions') public tippyOptions: Object;
constructor(private el: ElementRef) {
this.el = el;
}
public ngOnInit() {
tippy(this.el.nativeElement, this.tippyOptions || {}, true);
}
}
你也可以使用生命周期钩子 ngAfterViewInit 然后你不需要 setTimeout。
public ngAfterViewInit() {
this.loadTippy();
}
这适用于 tippy.js 6.x
@Directive({selector: '[tooltip],[tooltipOptions]'})
export class TooltipDirective implements OnDestroy, AfterViewInit, OnChanges {
constructor(private readonly el: ElementRef) {}
private instance: Instance<Props> = null;
@Input() tooltip: string;
@Input() tooltipOptions: Partial<Props>;
ngAfterViewInit() {
this.instance = tippy(this.el.nativeElement as Element, {});
this.updateProps({
...(this.tooltipOptions ?? {}),
content: this.tooltip,
});
}
ngOnDestroy() {
this.instance?.destroy();
this.instance = null;
}
ngOnChanges(changes: SimpleChanges) {
let props = {
...(this.tooltipOptions ?? {}),
content: this.tooltip,
};
if (changes.tooltipOptions) {
props = {...(changes.tooltipOptions.currentValue ?? {}), content: this.tooltip};
}
if (changes.tooltip) {
props.content = changes.tooltip.currentValue;
}
this.updateProps(props);
}
private updateProps(props: Partial<Props>) {
if (this.instance && !jsonEqual<any>(props, this.instance.props)) {
this.instance.setProps(this.normalizeOptions(props));
if (!props.content) {
this.instance.disable();
} else {
this.instance.enable();
}
}
}
private normalizeOptions = (props: Partial<Props>): Partial<Props> => ({
...(props || {}),
duration: props?.duration ?? [50, 50],
});
}
使用这个看起来像:
<button [tooltip]="'Hello!'">Hover here</button>
<button [tooltip]="'Hi!'" [tooltipOptions]="{placement: 'left'}">Hover here</button>
我有一个包含以下代码的指令
import { Directive, Input, OnInit, ElementRef, SimpleChanges, OnChanges } from '@angular/core';
import tippy from 'tippy.js';
@Directive({
selector: '[tippy]'
})
export class TippyDirective implements OnInit, OnChanges {
@Input('tippyOptions') public tippyOptions: Object;
private el: any;
private tippy: any = null;
private popper: any = null;
constructor(el: ElementRef) {
this.el = el;
}
public ngOnInit() {
this.loadTippy();
}
public ngOnChanges(changes: SimpleChanges) {
if (changes.tippyOptions) {
this.tippyOptions = changes.tippyOptions.currentValue;
this.loadTippy();
}
}
public tippyClose() {
this.loadTippy();
}
private loadTippy() {
setTimeout(() => {
let el = this.el.nativeElement;
let tippyOptions = this.tippyOptions || {};
if (this.tippy) {
this.tippy.destroyAll(this.popper);
}
this.tippy = tippy(el, tippyOptions, true);
this.popper = this.tippy.getPopperElement(el);
});
}
}
并使用指令如下
<input tippy [tippyOptions]="{
arrow: true,
createPopperInstanceOnInit: true
}" class="search-input" type="text"
(keyup)="searchInputKeyDown($event)">
如何在 mouseenter 或 focus 上显示 Tippy,因为这些是默认触发器,从我在指令中的 tippy 实例,这是我在第 44 行 console.log(this.tippy)
时得到的结果
{
destroyAll:ƒ destroyAll()
options:{placement: "top", livePlacement: true, trigger: "mouseenter focus", animation: "shift-away", html: false, …}
selector:input.search-input
tooltips:[]
}
当我尝试使用时出现错误
this.popper = this.tippy.getPopperElement(el);
ERROR TypeError: _this.tippy.getPopperElement is not a function
如何让这个指令生效,因为我是从 github
的仓库中获取它的https://github.com/tdanielcox/ngx-tippy/blob/master/lib/tippy.directive.ts
我在这里缺少什么,感谢任何帮助,谢谢
我不确定他们在您包含的链接回购中试图完成什么。要使 tippy.js
正常工作,您应该能够将指令更改为以下内容:
import { Directive, Input, OnInit, ElementRef } from '@angular/core';
import tippy from 'tippy.js';
@Directive({
/* tslint:disable-next-line */
selector: '[tippy]'
})
export class TippyDirective implements OnInit {
@Input('tippyOptions') public tippyOptions: Object;
constructor(private el: ElementRef) {
this.el = el;
}
public ngOnInit() {
tippy(this.el.nativeElement, this.tippyOptions || {}, true);
}
}
你也可以使用生命周期钩子 ngAfterViewInit 然后你不需要 setTimeout。
public ngAfterViewInit() {
this.loadTippy();
}
这适用于 tippy.js 6.x
@Directive({selector: '[tooltip],[tooltipOptions]'})
export class TooltipDirective implements OnDestroy, AfterViewInit, OnChanges {
constructor(private readonly el: ElementRef) {}
private instance: Instance<Props> = null;
@Input() tooltip: string;
@Input() tooltipOptions: Partial<Props>;
ngAfterViewInit() {
this.instance = tippy(this.el.nativeElement as Element, {});
this.updateProps({
...(this.tooltipOptions ?? {}),
content: this.tooltip,
});
}
ngOnDestroy() {
this.instance?.destroy();
this.instance = null;
}
ngOnChanges(changes: SimpleChanges) {
let props = {
...(this.tooltipOptions ?? {}),
content: this.tooltip,
};
if (changes.tooltipOptions) {
props = {...(changes.tooltipOptions.currentValue ?? {}), content: this.tooltip};
}
if (changes.tooltip) {
props.content = changes.tooltip.currentValue;
}
this.updateProps(props);
}
private updateProps(props: Partial<Props>) {
if (this.instance && !jsonEqual<any>(props, this.instance.props)) {
this.instance.setProps(this.normalizeOptions(props));
if (!props.content) {
this.instance.disable();
} else {
this.instance.enable();
}
}
}
private normalizeOptions = (props: Partial<Props>): Partial<Props> => ({
...(props || {}),
duration: props?.duration ?? [50, 50],
});
}
使用这个看起来像:
<button [tooltip]="'Hello!'">Hover here</button>
<button [tooltip]="'Hi!'" [tooltipOptions]="{placement: 'left'}">Hover here</button>