小编Nao*_*mor的帖子

从 ngOnChanges 更改组件输入,同时使用 OnPush 策略

我在使用 Angular 6 应用程序时遇到问题:

问题

假设我有 2 个组件:父组件和子组件。

孩子有2个输入。当 1 个输入发生变化时,在 ngOnChanges() 中,子组件向父组件发出一些东西。

然后父组件更改子组件的第二个输入。我希望再次调用子组件的更改检测 - 但事实并非如此。子组件的视图显示了第二个输入的旧值。


辩解

该申请有以下定义:

  1. 所有组件都使用变更检测策略 OnPush。包括根组件。
  2. 我正在使用 ngrx 商店。在减速器中调用 markForCheck() 或 detectChanges() 不是一个选项。
  3. 数据使用异步管道向下传输到子组件,因为它来自使用选择器(可观察)的存储。
  4. 我不能更早地导致第二个输入的更改(例如在父组件中)-它必须在子组件接收到第一个输入的更改之后发生。

为了说明这个案例,我创建了一个简单的演示项目。在那里我不使用商店,所以我没有任何选择器......相反,我使用 rxjs Subject 来使用异步管道。

这里是:

https://angular-ccejq4.stackblitz.io

查看控制台以了解会发生什么以及何时发生。


糟糕的解决方案

我已经尝试过的:

  1. 将根组件的更改检测策略更改为默认值。它有效,但这不是一个好的解决方案,因为它会导致性能问题。
  2. 在发出(!)之前和之后调用 markForCheck() - 不工作。
  3. 在发出(!)之前和之后调用detectchanges() - 不工作。
  4. 在父组件订阅选择器而不是使用异步管道 - 不工作。
  5. 从 setTimeout 中调用发射 - 它有效。但有更好的解决方案吗?一个更 Angular 驱动的。因为这个解决方案更像是一种解决方法。
  6. 使用 ngAfterViewInit/ngAfterViewChecked 并发出,从那里调用 markForCheck() 和 detectChanges() - 不工作。

我发现新值到达异步管道。然后异步管道调用 markForCheck()。但它不会调用detectChanges()..所以更改检测周期不会运行。视图只会在下一个更改检测周期时正确更改 - 正如您在我的演示应用程序中看到的那样。


有任何想法吗?

谢谢!

rxjs ngrx angular2-changedetection angular angular-changedetection

5
推荐指数
1
解决办法
602
查看次数