typescript 来自组件的 Angular 2 getBoundingClientRect

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37881169/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:34:37  来源:igfitidea点击:

Angular 2 getBoundingClientRect from component

javascripttypescriptangular

提问by lbrahim

I have component like below which is basically a popover:

我有像下面这样的组件,它基本上是一个弹出窗口:

import {Component, Input, ViewChild} from 'angular2/core'

declare var $: any;

@Component({
  selector: 'popover',
  template: `
  <div id="temp" [ngStyle]="{'position':'absolute', 'z-index':'10000', 'top': y + 'px', left: x + 'px'}"
       [hidden]="hidden" #temp>
    <ng-content></ng-content>
  </div>
  `
})
export class Popover {

  @ViewChild("temp") temp;

  private hidden: boolean = true;
  private y: number = 0;
  private x: number = 0;

  show(target, shiftx = 0, shifty = 0){
    let position = $(target).offset();
    this.x = position.left + shiftx;
    this.y = position.top + shifty;
    this.hidden = false;

    console.log("#temp", this.temp.nativeElement.getBoundingClientRect()); //all 0s
    console.log("temp id", document.getElementById('temp').getBoundingClientRect()); //all 0s
  }

  hide(){
    this.hidden = true;
  }
}

Inside the show()method I am trying to get the result of getBoundingClientRect()but its returning 0for all properties but when I type in document.getElementById("temp").getBoundingClientRect()from Chrome's console I get proper result with actual values in the properties. Why the difference and what can I do to get the actual value from my component?

在该show()方法中,我试图获取结果,getBoundingClientRect()但它返回0所有属性,但是当我document.getElementById("temp").getBoundingClientRect()从 Chrome 的控制台输入时,我得到了正确的结果以及属性中的实际值。为什么会有差异,我该怎么做才能从我的组件中获得实际值?

采纳答案by lbrahim

For some reason, the DOM was not updated right after it was shown so, a setTimeoute.g. 10 did the trick.

出于某种原因,DOM 在显示后没有立即更新,setTimeout例如 10 就成功了。

回答by Anca Spatariu

Instead of using setTimeout or lifecycle hooks that can be triggered more than once, I solved it with setting the Renderer to watch the window load event.

我没有使用可以多次触发的 setTimeout 或生命周期钩子,而是通过设置渲染器来观察窗口加载事件来解决它。

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

...

export class MyComponent implements  OnInit {

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

    ngOnInit() {
        this.render.listen('window', 'load', () => {
            const rect = this.el.nativeElement.getBoundingClientRect().top;
        })
    }

}

Maybe this helps someone's usecase.

也许这有助于某人的用例。

回答by Carol Cabral

I would use ngAfterContentChecked(). It works perfectly fine for me.

我会使用 ngAfterContentChecked()。它对我来说非常好。

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

export class ModelComponent implements AfterContentChecked  {
   ngAfterContentChecked() {
        //your code
    }
}

I hope it helps. :)

我希望它有帮助。:)

回答by Gurung

In this context, ngAfterContentCheckedworks. As answered above.

在这种情况下,ngAfterContentChecked作品。如上所述。

ngAfterContentCheckedhook method runs last in the lifecycle before the ngOnDestroy. You can read more about Lifecycle Hooks here.

ngAfterContentCheckedhook 方法在ngOnDestroy. 您可以在此处阅读有关 Lifecycle Hook 的更多信息。

Also be careful what you do in here, as it may result into performance issue.

还要小心你在这里所做的,因为它可能会导致性能问题。

Timing

Called after the ngAfterViewInit() and every subsequent ngAfterContentChecked().

定时

在 ngAfterViewInit() 和每个后续的 ngAfterContentChecked() 之后调用。