gpt4 book ai didi

angular - 为什么即使 *ngIf 设置为 true,@ViewChild 仍然未定义

转载 作者:行者123 更新时间:2023-12-04 13:34:05 25 4
gpt4 key购买 nike

我遇到了以下问题,该问题已由 {static: false} 修复房产在@ViewChild .
这个 stackoverflow Q/A 帮助解决了这个问题 How should I use the new static option for @ViewChild in Angular 8? .
我想更好地理解这个场景以及如何static更改结果,以及更改检测如何影响此场景。我在 angular 文档中阅读了一些关于更改检测的内容,发现非常缺乏。
我想出了一个 stackblitz 来说明一些我不明白的东西。 Stackblitz angular example
点击时 toggle按钮两次,我在命令行上得到以下信息:

> undefined undefined
> undefined undefined
> undefined ElementRef {nativeElement: div}
> undefined ElementRef {nativeElement: div}

不过我希望:
> undefined undefined
> undefined ElementRef {nativeElement: div}
> ElementRef {nativeElement: div} ElementRef {nativeElement: div}
> ElementRef {nativeElement: div} ElementRef {nativeElement: div}

这是代码的逻辑——(请参阅 stackblitz 中的完整代码)
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
@ViewChild("contentPlaceholder", { static: true })
trueViewChild: ElementRef;

@ViewChild("contentPlaceholder", { static: false })
falseViewChild: ElementRef;

display = false;

constructor() {}

show() {
console.log(this.trueViewChild, this.falseViewChild);
this.display = true;
console.log(this.trueViewChild, this.falseViewChild);
}
}

我的问题是:
  • 为什么this.falseViewChild的第二行值显示为未定义。设置后不应该更改检测this.display = false因此它不应该是未定义的?
  • 为什么this.trueViewChild保持未定义。我希望它能在 *ngIf 之后找到元素变成真的?
  • 最佳答案

    Angular 变化检测在 zone.js 库的帮助下工作。 更新 ViewChild/Content 查询发生在变更检测周期 .
    zone.js 库修补异步 API(addEventListener、setTimeout()、Promises...)并确切知道执行了哪个任务以及何时完成。
    例如,它可以监听点击事件并在 时发出通知。此任务已完成 (没有待处理的任务,这意味着该区域变得稳定)。
    Angular 订阅这些通知以执行更改检测 跨越所有组件三个从根组件开始。

    // your code 
    (click)="someHandler()"

    someHandler() {
    ....
    }

    // angular core
    checkStable() {
    if (there is no any task being executed and there is no any async pending request) {
    PERFORM CHANGE DETECTION
    }
    }
    关于代码中的顺序如下:
     click
    ||
    \/
    someHandler()
    ||
    \/
    checkStable()
    ||
    \/
    PERFORM CHANGE DETECTION
    那么,让我们回答你的问题:
  • 为什么 this.falseViewChild 的第二行值显示为未定义。设置 this.display = false 后不应该运行更改检测,因此它不应该是未定义的吗?

  • 改变时没有反应 display属性(property)
    show() {
    console.log(this.trueViewChild, this.falseViewChild);
    this.display = true; <--- Angular doesn't do here anything, it only listens to zone state changes
    console.log(this.trueViewChild, this.falseViewChild); // nothing should be updated here
    // because there wasn't any cd cycle yet
    }
    这就是为什么您在第一次点击时会得到以下输出:
    > undefined undefined
    > undefined undefined <---- nothing has updated

    ......
    update happens here
    它稍后会更新,但除非您再次单击,否则您将看不到此内容,因为您稍后不会记录这些值。
  • Why does this.trueViewChild stay undefined. I would expect it to find the element after the *ngIf becomes true?

  • 因为有来自 Angular documentation 的规则:

    With static queries (static: true), the query resolves once the viewhas been created, but before change detection runs. The result,though, will never be updated to reflect changes to your view, such aschanges to ngIf and ngFor blocks.


    这意味着如果它最初是 false (例如,它在 *ngIf 或 ng-template 内)那么它总是 false

    关于angular - 为什么即使 *ngIf 设置为 true,@ViewChild 仍然未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63255676/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com