【问题标题】:Why a ViewChild ElementRef has 0 width and height in ngAfterViewInit?为什么在 ngAfterViewInit 中 ViewChild ElementRef 的宽度和高度为 0?
【发布时间】:2019-04-07 20:01:41
【问题描述】:

我正在尝试根据元素的宽度和高度进行一些计算,但由于某种原因,这些在 AfterViewInit 生命周期挂钩上无法立即使用(两者均为 0)。
虽然setTimeout 似乎确实可以解决问题,但我不喜欢它。

这是什么原因造成的? 有没有更优雅的解决方案?

@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

<div class"main" #main>
  <app-toolbar></app-toolbar>
  <app-list></app-list>
</div>

【问题讨论】:

  • 我的第一个想法是,想想事情发生的速度有多快,一开始你有一个渲染的 dom,但它有样式吗?高度是多少?

标签: javascript html angular


【解决方案1】:

必须使用ngAfterViewChecked生命周期钩子 ,而不是ngAfterViewInit。 正如 Angular 文档所说的 ngAfterViewChecked()

在 Angular 检查组件的视图和 子视图后响应 / 指令所在的视图

在 ngAfterViewInit() 之后调用 ngAfterContentChecked()。

【讨论】:

    【解决方案2】:

    除非您在 &lt;app-toolbar&gt;&lt;app-list&gt; 中的模板中有任何异步更改,否则这应该可以工作。

    您可以在此处查看示例:

    https://stackblitz.com/edit/angular-stack-afterviewinit-55563149?file=src%2Fapp%2Fapp.component.ts

    如果您看到此示例,#mainDiv 在呈现后会进行更改(在此示例中为 setTimeout,但它可以是任何异步的,例如订阅和 ajax 请求)同时#syncDiv 会同步加载所有内容。

    【讨论】:

      猜你喜欢
      • 2020-06-12
      • 2012-08-05
      • 1970-01-01
      • 1970-01-01
      • 2014-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多