问题描述
我在stackblitz链接中添加了2个表,如果我将鼠标悬停在第一个表(第1列)的其他行中,则会在上方打开工具提示( 预期 ),但是当我们向下滚动时页面,然后将鼠标悬停在第二个表的最后一行,工具提示将隐藏在屏幕底部,如果我只有一个表,则情况并非如此.我期望工具提示会在上方打开,而不是隐藏在底部.请提出建议.
I have added 2 tables in stackblitz link, if I hover in first table(1st column) alst rows the tooltip opens above(expected) but when we scroll down the page and then hover on the last rows of 2nd table, the tooltip gets hidden in the bottom of the screen, as was not the case if I have a single table.I was expecting the tooltip to be opened above instead of getting hidden in the bottom. Please suggest.
Stacblitz链接
https://stackblitz .com/edit/angular-mat-tooltip-ctvigc?file = app%2Ftooltip-overview-example.html
tooltip-overview-example.html
<ng-container matColumnDef="Column1">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Alert </th>
<td mat-cell *matCellDef="let row; let i = index" customToolTip [contentTemplate]="template">
<span >{{row.Column1}}</span>
<!--TOOLTIP-->
<ng-template #template>
<div style="display: flex; flex-direction: column">
<span>{{row.conditionals | json}}</span>
<button (click)="onClick(i)">Click</button>
</div>
</ng-template>
</td>
</ng-container>
在CustomToolTipComponent中扩展了角材料TooltipComponent
Extended the Angular material TooltipComponent in CustomToolTipComponent
custom-tool-tip.component.ts
import {
Component,
OnInit,
OnDestroy,
Input,
TemplateRef
} from "@angular/core";
import {TooltipComponent} from "@angular/material/tooltip"
import { Observable, Subject } from "rxjs";
@Component({
selector: "app-custom-tool-tip",
templateUrl: "./custom-tool-tip.component.html",
styleUrls: ["./custom-tool-tip.component.css"]
})
export class CustomToolTipComponent extends TooltipComponent {
@Input() text: string;
@Input() contentTemplate: TemplateRef<any>;
}
custom-tool-tip.component.html
<div>
<div class="tooltip-conatiner">
<ng-template #simpleText>
{{text}}
</ng-template>
<ng-container *ngTemplateOutlet="contentTemplate || simpleText">
</ng-container>
</div>
</div>
tool-tip-renderer.directive.ts
@Directive({
selector: "[customToolTip]"
})
export class ToolTipRendererDirective {
@Input() showToolTip: boolean = true;
//If this is specified then specified text will be showin in the tooltip
@Input(`customToolTip`) text: string;
//If this is specified then specified template will be rendered in the tooltip
@Input() contentTemplate: TemplateRef<any>;
private _overlayRef: OverlayRef;
private _tooltipInstance;
private _mouseInTooltip: boolean = false;
private _hasListeners: boolean = false;
constructor(
private _overlay: Overlay,
private _overlayPositionBuilder: OverlayPositionBuilder,
private _elementRef: ElementRef,
private _r2: Renderer2
) {}
ngOnInit() {
if (!this.showToolTip) {
return;
}
const positionStrategy = this._overlayPositionBuilder
.flexibleConnectedTo(this._elementRef)
.withPositions([
{
originX: "center",
originY: "bottom",
overlayX: "center",
overlayY: "top",
offsetY: -10
}
]);
this._overlayRef = this._overlay.create({ positionStrategy });
}
@HostListener("mouseenter")
show(e) {
if (this._overlayRef && !this._overlayRef.hasAttached()) {
//set tooltip instance
this._tooltipInstance = this._overlayRef.attach(
new ComponentPortal(CustomToolTipComponent)
).instance;
//set CustomToolTipComponenet content/inputs
this._tooltipInstance.text = this.text;
this._tooltipInstance.contentTemplate = this.contentTemplate;
//render tooltip
this._tooltipInstance!.show(0);
//sub to detach after hide anitmation is complete
this._tooltipInstance
.afterHidden()
.pipe(take(1))
.subscribe(() => {
this._overlayRef.detach();
});
if (!this._hasListeners) {
this._hasListeners = true;
//attach mouseleave listener to detach when mouseleave on tooltip
this._r2.listen(this._overlayRef.overlayElement, "mouseleave", () => {
//call hide function in this directive
this._mouseInTooltip = false;
this.hide();
});
this._r2.listen(this._overlayRef.overlayElement, "mouseenter", () => {
//call hide function in this directive
this._mouseInTooltip = true;
});
}
}
}
@HostListener("mouseleave")
hide(buttonClicked = null) {
if(buttonClicked)
this._mouseInTooltip = false;
setTimeout(() => {
if (!this._mouseInTooltip) this._tooltipInstance!._onHide.next();
}, 20);
}
}
推荐答案
要解决此问题,您需要将cdk版本升级到7.3.7,该版本在OverlayRef上有一个新方法,称为updatePositionStrategy.
To fix this, you need to upgrade your cdk version to 7.3.7 which has a new method on OverlayRef as updatePositionStrategy.
根据此方法,您可以在粘贴后更改叠加层的位置策略.
According to this method you can change the position strategy of an overlay after attach.
在附加组件之后,您需要在show功能中更新位置策略,如下所示:
In your show function after attaching the component you need to update position strategy as below:
this._overlayRef.updatePositionStrategy(this._overlayPositionBuilder
.flexibleConnectedTo(this._elementRef)
.withPositions([{
originX: "center",
originY: "bottom",
overlayX: "center",
overlayY: "top",
offsetY: this.getOffsetY()
}]));
this._overlayRef.updatePosition();
其中this.getOffsetY()是私有方法,根据元素当前位置提供偏移y值.您可能需要更新此逻辑.
where this.getOffsetY() is private method provide offset y value based on element current position. You may need to update this logic.
private getOffsetY() {
if (this._elementRef.nativeElement.getBoundingClientRect().bottom > 500)
return -400;
if (this._elementRef.nativeElement.getBoundingClientRect().bottom > 400)
return -300;
if (this._elementRef.nativeElement.getBoundingClientRect().bottom > 300)
return -200;
return -10;
}
这是stackblitz 链接
Here is stackblitz link
这篇关于滚动页面时在上方打开角度材质的工具提示,并避免工具提示被隐藏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!