【问题标题】:How to get the dimensions of a Component in Angular 5 before rendering it?如何在渲染之前在 Angular 5 中获取组件的尺寸?
【发布时间】:2018-10-01 09:08:48
【问题描述】:

我在 Angular 5 中实现了一个通用工具提示。为了正确定位(尤其是相对于目标元素居中),我需要在渲染它之前获取工具提示的宽度和高度。

我已经知道如何从this question 获取组件的尺寸。但是,我需要先设置工具提示的内容(让浏览器确定大小)来计算位置。然后,第二,我想设置位置并添加一个类来显示它。

这是我的代码:

// tooltip.component.html
<div class="popup fade"
  [ngClass]="tooltip?.isOpen ? 'show' : ''"
  [style.left.px]="calculatedPos?.left"
  [style.top.px]="calculatedPos?.top">
  {{ tooltip?.text }}
</div>

// tooltip.component.ts
export class TooltipComponent {
  public tooltip: any;
  public calculatedPos: TooltipPosition = {
    left: 0,
    top: 0
  }

  constructor(private store: Store<any>, private ref: ElementRef) {
    this.store.subscribe((state) => this.render(state));
  }

  render () {
    let targetRect = this.tooltip.targetEl 
          && this.tooltip.targetEl.nativeElement
          && this.tooltip.targetEl.nativeElement.getBoundingClientRect()
          || null;
    let tooltipRect = this.ref 
          && this.ref.nativeElement
          && this.ref.nativeElement.getBoundingClientRect()
          || null;
    if (targetRect && tooltipRect) { // <-- tooltipRect.height /.width is zero here!
      switch (this.tooltip.placement) {
        case 'right':
          this.calculatedPos = this.calculatePositionRight(targetRect, tooltipRect, this.tooltip.offset)
          break;
          // and so on...
  }
}

我尝试使用生命周期钩子:

  • ngAfterContentChecked 导致相同的结果
  • ngAfterViewChecked 给了我一个(可预见的)ExpressionChangedAfterItHasBeenCheckedError
  • 渲染时根本不调用ngOnChanges

所以:如何在渲染内容之前获取组件的尺寸?或者如何检测正在呈现的内容然后更新位置?

我的下一个想法是使用超时来首先让组件呈现,然后设置位置(没有用户注意到) - 但也许有一个最佳实践,我还不知道。

【问题讨论】:

  • 您无法从尚未由 DOM 计算的元素中获取高度。所以就像你建议的那样;让它渲染和隐藏,或者给元素一个固定的宽度。注意使用%设置宽度也是可以的。

标签: angular typescript


【解决方案1】:

为了得到一个元素的尺寸,你必须等待它被渲染。

如果元素不存在于 DOM 中,则无法获取其尺寸。

使用ngAfterViewInit,此时视图已初始化。

【讨论】:

  • 我用ngAfterViewInit 尝试过,但它只被调用一次。然而,工具提示每次都会被不同的内容重用。正如我所说,我也不能使用ngAfterViewChecked...
【解决方案2】:

我认为在ngAfterViewInit 中设置订阅是没有办法的。要绕过ExpressionChangedAfterItHasBeenCheckedError,你可以告诉 Angular 你“知道你在做什么”。注入ChangeDetectorRef 并在render-Method 的末尾放置一个detectChanges-invocation。

【讨论】:

    猜你喜欢
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多