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
Angular 2 getBoundingClientRect from component
提问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 0
for 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 setTimeout
e.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, ngAfterContentChecked
works. As answered above.
在这种情况下,ngAfterContentChecked
作品。如上所述。
ngAfterContentChecked
hook method runs last in the lifecycle before the ngOnDestroy
. You can read more about Lifecycle Hooks here.
ngAfterContentChecked
hook 方法在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() 之后调用。