同步代码中不会进行更改检测

时间:2019-05-22 05:09:38

标签: javascript angular typescript

我正在研究一个组件,该组件具有一个可切换布尔值的按钮。该布尔值应该确定是否需要重新呈现HTML中的子组件,因为我希望重新运行子组件中的ngOnInit函数。

此情况在以下应用程序组件中进行了描述:https://codesandbox.io/s/angular-qxtm8

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

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

我不确定100%为什么onTestClickThree无效,而onTestClickTwo无效。

我的猜测如下:

  1. onTestClickTwo之所以有效,是因为在执行事件处理程序之后运行Angular中的更改检测。这样,它将检测到布尔值已设置为true。之后,事件循环将获取setTimeout的回调并将其放入堆栈。结束回调后,Angular将执行更改检测。

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

1 个答案:

答案 0 :(得分:0)

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

当然,在您的示例中,这没什么大不了的。但是,对于完全编码的组件(进行http调用,拥有子对象和所有对象)会发生什么情况?这将导致一些严重的性能问题。

您应该使用函数来代替重新渲染组件。

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

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