简体   繁体   English

为什么异步函数导致在 ngOnInit() 中未定义 ViewChild

[英]Why is async function causing ViewChild to be undefined in ngOnInit()

Here is by Component which has a ViewChild referring to #h1 in the html:这是由 Component ,它有一个 ViewChild 引用 html 中的#h1

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);
  }
}

Why this.h1 is undefined at console.log('h1:' + this.h1);为什么this.h1console.log('h1:' + this.h1);undefined console.log('h1:' + this.h1); ? ?

Update 2020 Nov You wouldn't be in this situation if you are using latest Angularv9 which has static option on @ViewChild . 2020 年 11 月更新,如果您使用的是最新的 Angularv9,它在 @ViewChild 上具有静态选项, @ViewChild您就不会处于这种情况。

Because, since the condition passed to ngIf hasn't been reevaluated by the change detection at that point, the element is not in the view yet.因为,由于此时传递给 ngIf 的条件尚未被更改检测重新评估,因此该元素尚未出现在视图中。

You need to understand that change detection, and dom updates, aren't done after each and every instruction of your code.您需要了解更改检测和 dom 更新不是在您的代码的每条指令之后完成的。 Even if that was possible, it would make the performance horrible.即使这是可能的,它也会使性能变得糟糕。

The loop is basically循环基本上是

  1. detect an event (like a timeout, or an asynchronous http response, or some dom event like a click)检测事件(如超时,或异步 http 响应,或某些 dom 事件,如单击)
  2. execute the code handling this event执行处理此事件的代码
  3. detect the changes in the state of the components, and in the expressions used in the template (like showh1 )检测组件状态的变化,以及模板中使用的表达式(如showh1
  4. update the DOM更新 DOM
  5. go to 1去 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM