首页 > 解决方案 > 即使 ViewChildren 没有发生更改,也会触发 ViewChildren.changes.subscribe

问题描述

我正在开发一个有父组件和子组件列表的角度应用程序。父级使用两个 api 调用:

我想通过 ViewChildren 装饰器和 ngAfterViewInit 为每个孩子添加一个属性,所以我将以下内容放在父级中。

  @ViewChildren(ChildrenComponent) children: QueryList<ChildrenComponent>;


  ngAfterViewInit() {
    this.children.changes.subscribe((children) => {
       children.forEach((child) => {
           child = 'Property!!'; // this string is dynamic in my app.
       })
    });
  }

API 调用 A 返回后触发订阅。这是意料之中的,因为 QueryList 中添加了一个新子项。但是,在 API 调用 B 返回后,它也会被调用。

根据有关 ViewChildren 装饰器的文档,它应该只在从 QueryList 中添加、移动、删除子项时调用。但是,API 调用 B 仅触及子级之外的 div。为什么会触发订阅?

我已经包含了一个沙盒来说明这种行为:https ://codesandbox.io/s/angular-fll6r

ViewChildren 文档:https ://angular.io/api/core/ViewChildren

标签: angularangular-directiveangular-changedetection

解决方案


您的 apiARes 将在 1 秒后激活。在此期间,父级内部没有加载子级。出于演示目的,您将undefined在检查时得到

 ngOnInit() {
    console.log(this.children) //undefined
    // API call A
}

一旦调用 API,就会加载子级,这是对子级的更改检测。你会得到查询结果

setTimeout(() => {
      this.apiARes = true;
      console.log(this.children) // Query result
    }, 1000);

ngAfterViewInit()在最初渲染 child 的视图后调用。这就是为什么@ViewChildren()依赖它。在渲染子成员之前,我们无法访问它们。


推荐阅读