Почему ViewChild ElementRef имеет 0 ширины и высоты в ngAfterViewInit?

#javascript #html #angular

#javascript #HTML #угловой

Вопрос:

Я пытаюсь выполнить некоторые вычисления на основе ширины и высоты элемента, но по какой-то причине они не сразу доступны в 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>
  

Комментарии:

1. Моя первая мысль, подумайте о том, как быстро все происходит, сначала у вас есть визуализация dom, но она еще не оформлена? Какова высота?

Ответ №1:

Необходимо использовать ngAfterViewChecked перехват жизненного цикла , а не ngAfterViewInit . Как говорится в Angular docs о ngAfterViewChecked() :

Ответьте после проверки Angular представлений компонента и дочерних представлений / представления, в котором находится директива.

Вызывается после ngAfterViewInit() и каждого последующего ngAfterContentChecked().

Ответ №2:

Это должно сработать, если у вас нет каких-либо асинхронных изменений в вашем шаблоне в <app-toolbar> или <app-list> .

Вы можете проверить пример здесь:

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

Если вы видите этот пример, #mainDiv внесите изменения после того, как он был отображен (setTimeout в этом примере, но это может быть что угодно асинхронное, например, подписки и запрос ajax), тем временем #syncDiv загружайте все синхронно.