Почему функция async не определяет ViewChild в ngOnInit ()

Вот компонент, у которого есть ViewChild, относящийся к #h1 в html:

import { Component, ElementRef, ViewChild } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
  <h1 #h1 *ngIf="showh1">
    Welcome to {{title}}!
  </h1>
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  public showh1: boolean = false;
  @ViewChild('h1') h1: ElementRef;
  ngOnInit() {
    setTimeout(() => { //http.get in actual scenario
      this.showh1 = true;
      console.log('h1:' + this.h1);   //h1:undefined
      setTimeout(() => {
        console.log('h2:' + this.h1); //h2:[object Object]
      }, 1);
    }, 1000);
  }
}

Почему this.h1 undefined на console.log('h1:' + this.h1);?

Обновление 2020 г., ноябрь. Вы не оказались бы в такой ситуации, если бы используете последнюю версию Angularv9, которая имеет static вариант на @ViewChild.


person Anand Rockzz    schedule 17.12.2017    source источник
comment
Вы можете запустить applicationRef.tick() после установки showh1, чтобы заставить его работать (см. этот ответ).   -  person ConnorsFan    schedule 18.12.2017


Ответы (1)


Поскольку, поскольку условие, переданное в ngIf, не было переоценено при обнаружении изменений в этот момент, элемент еще не находится в представлении.

Вы должны понимать, что обнаружение изменений и обновления dom не выполняются после каждой инструкции вашего кода. Даже если бы это было возможно, это сделало бы представление ужасным.

Цикл в основном

  1. обнаруживать событие (например, тайм-аут, асинхронный HTTP-ответ или какое-то событие dom, например щелчок)
  2. выполнить код, обрабатывающий это событие
  3. обнаруживать изменения в состоянии компонентов и в выражениях, используемых в шаблоне (например, showh1)
  4. обновить DOM
  5. go to 1
person JB Nizet    schedule 17.12.2017