我有下面的组件,基本上是一个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;
}
}
在show()
方法中我试图得到getBoundingClientRect()
的结果,但是它返回0
所有属性,但是当我从Chrome的控制台输入document.getElementById("temp").getBoundingClientRect()
时,我得到了适当的结果与属性中的实际值。为什么差异以及如何从我的组件中获取实际值?
答案 0 :(得分:4)
我没有使用可以多次触发的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;
})
}
}
也许这有助于某人的使用。
答案 1 :(得分:3)
我会使用ngAfterContentChecked()。它对我来说非常好。
import { AfterContentChecked } from '@angular/core';
export class ModelComponent implements AfterContentChecked {
ngAfterContentChecked() {
//your code
}
}
我希望它有所帮助。 :)
答案 2 :(得分:2)
出于某种原因,DOM在显示之后没有立即更新,例如setTimeout
10诀窍。
答案 3 :(得分:0)
在这种情况下,ngAfterContentChecked
有效。如上所述。
ngAfterContentChecked
挂钩方法在生命周期中最后一个运行在ngOnDestroy
之前。您可以阅读有关生命周期挂钩here的更多信息。
还请注意此处的操作,因为这可能会导致性能问题。
时间
在ngAfterViewInit()之后及其后的所有调用 ngAfterContentChecked()。