【问题标题】:ExpressionChangedAfterItHasBeenCheckedError with ViewChildren带有 ViewChildren 的 ExpressionChangedAfterItHasBeenCheckedError
【发布时间】:2019-11-01 15:37:21
【问题描述】:

我“修复”了这个错误,但我想确保我没有做我不应该做的事情,因为这感觉不对……

这是我设计的示例,我有两个组件 faqComponentquestionAnswerComponent

<app-faq>
  <ul>
    <li *ngFor="let questionsAnswer of questionsAnswers">
      {{ questionsAnswer.question }}
    </li>
  </ul>
  <app-question-answer
     question="1. Why Foo Bar when Baz?"
     slug="why-foo-bar-when-baz"
     [activeSlug]="currentSlug"
  >
    <p>
     Lorem ipsum dolor sit amet
    </p>
  </app-question-answer>
    ... // a lot more question answer components
</app-faq>

我希望该列表由父组件上的 questionsAnswer 组件动态生成,这是通过使用子视图以我想要的方式工作

@ViewChildren(QuestionAnswerComponent) questionsAnswers: QueryList<QuestionAnswerComponent>;

除了我在日志中得到一个ExpressionChangedAfterItHasBeenCheckedError(但它仍然为我呈现列表)

为了解决这个问题,我发现如果我将 faq 组件更改检测策略设置为 OnPush,然后在 ngAfterContentChecked 中触发 markForCheck(),它会消除该错误。

所以我的问题是为什么这很糟糕?还是有另一种方法我应该迭代 viewChildren?

【问题讨论】:

    标签: angular


    【解决方案1】:

    这是v8 中解决的问题,在 ViewChildren 和 ViewContent 上有明确的 static 标志。因此,如果您ng update @angular/core,更新原理图会将static: false 添加到您的questionAnswers,因为它会检测到它们是动态的,并且它们将在ngAfterViewInit 之后可用。

    另一方面,我不太确定此更改是否改进了更改检测并消除了异常,您可以升级并告诉我们:D 但您的方法似乎是正确的,因为这是我们必须避免此错误的方式v7,希望它不会在 v8 中发生。
    快乐的 ng 编码!

    【讨论】:

    • 很有趣,是的,在这个项目升级之前还需要一点时间,哈哈。不过好在我似乎有所了解,或者至少我们都错了哈哈
    • 呵呵,重现您在 StackBlitz 中加载数据的方式可能会很有趣,看看我们是否还需要进行一些手动更改检测,我希望不是 :D
    • 只是评论一下以供将来参考,v8 确实希望直接解决这个问题,这很好 angular.io/guide/static-query-migration 再次感谢 Mateo,我会接受你的回答。
    猜你喜欢
    • 1970-01-01
    • 2018-10-05
    • 2020-04-10
    • 2019-08-03
    • 1970-01-01
    • 2020-02-05
    • 2017-06-11
    • 2018-05-29
    • 1970-01-01
    相关资源
    最近更新 更多