【发布时间】:2017-09-25 07:43:09
【问题描述】:
我创建了一个 Angular 2 应用程序,其中包含一个组件,我试图将其 HTML 元素相对于另一个组件定位。为了计算准确的坐标,我需要知道浏览器呈现的我自己元素的宽度和高度。
我正在使用window.getComputedStyle(this.elementRef.nativeElement) 来获取这些属性。我注意到,在呈现页面时,属性会不断变化,直到页面呈现完成。为了了解任何更改并调整位置,我检查了组件的 ngAfterViewChecked 方法中的值。
然而,当渲染导致新的计算样式属性时,似乎ngAfterViewChecked 没有被调用,因为我发现我的钩子不再被调用,甚至尽管计算的样式属性仍在变化。我假设 Angular 框架并非旨在检测这种变化。
我的第一次尝试是实现ngDoCheck 钩子,但似乎这个钩子在一段时间后并且在计算的样式属性具有其最终值之前没有被调用。我假设我还没有完全理解这个钩子应该在什么时候被调用。
我终于发现,如果我在 ngAfterViewChecked 中实现 setTimeout 函数,这会导致稍后再次调用相同的钩子,即使我只传递了一个虚拟函数,例如:
setTimeout(() => {}, 500);
但坦率地说,我不明白为什么会这样。 谁能给我解释一下setTimeout和ngAfterViewChecked钩子之间的联系?
虽然这似乎是一个有点肮脏的解决方法:检测和处理计算样式属性变化的正确“Angular”方法是什么?
代码摘录:
export class MyComponent implements OnInit, AfterViewChecked
{
private cssWidth: number;
private cssHeight: number;
constructor(private elementRef: ElementRef, private renderer: Renderer2)
{
}
ngAfterViewChecked()
{
console.log("ngAfterViewChecked");
this.updateView();
}
public updateView()
{
const sizeX = parseFloat(window.getComputedStyle(this.elementRef.nativeElement).width) || 0;
const sizeY = parseFloat(window.getComputedStyle(this.elementRef.nativeElement.height) || 0;
if (sizeX === this.cssWidth && sizeY === this.cssHeight) {
// no change
return;
}
console.log("Change detected!");
// TODO Does not work without this dummy timeout function (else no more changes detected) - why so??
setTimeout(() => {}, 500);
[.. doing the positioning here ..]
}
【问题讨论】:
标签: javascript css angular dom getcomputedstyle