Angular2更改检测“检查后表达式已更改”

Angular2更改检测“检查后表达式已更改”

问题描述:

我在Angular2(最终版)中遇到了有关组件之间更改检测和数据流的问题。我已经解决了这个问题,但对我来说这似乎有点冒险 所以想知道是否有更好的方法来做到这一点。Angular2更改检测“检查后表达式已更改”

基本上我有一个具有一个子组件B和也* ngFor创建C.

子组件的数量对于每一个组分C组分A,存在定义了在父组件中处理的@Output A.根据该输出,确定组件A上的另一个属性(只是一个数字),在组件B上用作@Input

在DEV模式下,每次组件C中的@Output被触发,我在控制台中出现错误:

Expression has changed after it was checked. Previous value: XX. Current value: XX. 

从阅读中可以看出,它的类型是由于Angular2中的单向数据流引起的。我想知道如何在我的场景中正常工作?

我暂时在A组份注入ChangeDetectorRef并调用其detectChanges()方法,从C. 的实例处理@Output事件的函数我担心它的效率并不高寿。我可以尝试改进它,并且只在最后一个项目的事件(所有C组件同时发送该事件)之后调用它,但是然后我会担心事件的异步性质和一些意外行为。

有没有人有一个想法如何克服这个问题?我的设计在组件之间的数据流方面是否存在根本上的缺陷? 我应该去做一些共享服务而不是交换数据吗?

任何帮助非常感谢。

+0

当更改检测运行导致模型更改时,会引发错误。例如,如果您在更改检测调用的'ngOnChanges()'中更改模型。我们需要查看更多代码来追踪原因。当一个函数被绑定时,通常会导致它每次调用时都会返回一个新的对象实例。 –

+0

@GünterZöchbauer就是这样发生的事情。组件C的每个实例都有ngOnChanges(),它会发出事件并导致父组件A中的模型更改。那么应该避免哪些内容? – Zyga

你可以注入private cdRef:ChangeDetectorRef并在ngOnChanges()末调用this.cdRef.detectChanges()。通过这种方式,Angular会再次检测变化,并且不会抱怨以前修改的模型值。

class MyComponent { 
    constructor(private cdRef:ChangeDetectorRef) {} 

    ngOnChanges(changes) { 
    this.xxx = ... 
    ... 
    this.cdRef.detectChanges(); 
    } 
} 
+0

在我的情况下,它不会工作,如果我在ngOnChanges中这样做,就像发生在组件A的子组件中一样,然后更改组件A中另一个子组件B的值(通过将事件发回到A并更新相关属性用作孩子B的输入)。然而,它将在组件的A方法中处理从C接收的事件。我只是认为它在Angular2中做到了“哈克”,并且想知道是否应该重新考虑在组件之间传递数据的方式。 – Zyga

+0

通常使用共享服务与observables是一个好主意。观察对象不会导致变更检测。 –