【问题标题】:Change detection doesn't happen in synchronous codes同步代码中不会发生变化检测
【发布时间】:2019-10-08 12:28:04
【问题描述】:

我正在开发一个组件,该组件具有一个用于切换布尔值的按钮。这个布尔值应该确定 HTML 中的子组件是否需要重新渲染,因为我希望重新运行子组件中的 ngOnInit 函数。

这里的app组件中描述了这种情况:https://codesandbox.io/s/angular-qxtm8

app.component 是父级,second.component 是子级。

我尝试了三种不同的解决方案。它们是onTestClickOneonTestClickTwoonTestClickThreeapp.component.tsonTestClickOneonTestClickTwo 成功地重新触发了子组件中的ngOnInit。每当我单击相应的按钮时,我们可以看到控制台日志打印在控制台上。但是,onTestClickThree 没有用。

我不是 100% 确定为什么 onTestClickThree 不起作用,而 onTestClickTwo 起作用。

我的猜测如下:

  1. onTestClickTwo 有效,因为 Angular 中的更改检测是在事件处理程序执行后运行的。因此,它会检测到布尔值是否已设置为真。之后,事件循环会得到setTimeout的回调,并入栈。 Angular 会在回调结束后执行变更检测。

  2. onTestClickThree 不起作用,因为当 Angular 运行更改检测时,布尔值已经为真。 Angular 不知道它已被更改。

【问题讨论】:

标签: javascript angular typescript


【解决方案1】:

让我们解决那里的主要问题,即您的设计:为什么要重新渲染组件以再次触发ngOnInit

当然,就您的示例而言,这没什么大不了的。但是对于一个完全编码的组件,进行 http 调用,有孩子等等会发生什么?这将导致一些严重的性能问题。

您应该使用函数来执行此操作,而不是重新渲染组件。

如果事件(最初应该重新渲染组件)来自子级,则使用@Output。如果它来自父级,请使用 @ViewChild 引用。

As you can see 运行良好,没有任何检测问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-18
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多