[英]Why a ViewChild ElementRef has 0 width and height in ngAfterViewInit?
I'm trying to do some calculations based on element width and height, but for some reason, those are not immediately available on the AfterViewInit
lifecycle hook (both are 0). 我正在尝试根据元素的宽度和高度进行一些计算,但是由于某些原因,
AfterViewInit
生命周期挂钩(两者均为0)无法立即使用这些AfterViewInit
。
Though setTimeout
does seem to do the trick, I don't like it. 尽管
setTimeout
确实可以解决问题,但我不喜欢它。
What causing this? 是什么原因造成的? Is there a more elegant solution?
有没有更优雅的解决方案?
@ViewChild('main') mainDiv: ElementRef;
ngAfterViewInit() {
this.printMainHeight() // 0
// with setTimeout width is correctly retrieved ...
setTimeout(() => this.printMainHeight()) // 430
}
printMainHeight() {
console.log(this.mainDiv.nativeElement.getBoundingClientRect().height)
}
HTML 的HTML
<div class"main" #main>
<app-toolbar></app-toolbar>
<app-list></app-list>
</div>
It is necessary to use ngAfterViewChecked
lifecycle hook , not ngAfterViewInit
. 必须使用
ngAfterViewChecked
生命周期挂钩,而不是ngAfterViewInit
。 As Angular docs says about ngAfterViewChecked()
: 就像Angular的文档所说的
ngAfterViewChecked()
:
Respond after Angular checks the component's views and child views / the view that a directive is in.
Angular检查组件的视图和子视图/指令所在的视图后响应。
Called after the ngAfterViewInit() and every subsequent ngAfterContentChecked().
在ngAfterViewInit()及其之后的每个ngAfterContentChecked()之后调用。
That should work unless you have any asynchronous changes in your template in the <app-toolbar>
or the <app-list>
. 除非您在
<app-toolbar>
或<app-list>
中的模板中进行了异步更改,否则该方法应该有效。
You can check the example here: 您可以在此处查看示例:
https://stackblitz.com/edit/angular-stack-afterviewinit-55563149?file=src%2Fapp%2Fapp.component.ts https://stackblitz.com/edit/angular-stack-afterviewinit-55563149?file=src%2Fapp%2Fapp.component.ts
If you see this example, the #mainDiv
make changes after it was rendered (setTimeout in this example, but it can be anything async, like subscriptions and ajax request) meanwhile the #syncDiv
load everything synchronous. 如果您看到此示例,则
#mainDiv
在呈现后进行更改(在此示例中为setTimeout,但可以是任何异步内容,例如订阅和ajax请求),同时#syncDiv
同步加载所有内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.