markForCheck不触发子ngOnChanges生命周期钩子

时间:2018-03-05 10:55:34

标签: angular typescript

我有两个组成部分;父母和孩子,通过@Input@Output属性装饰者进行通信。即,Parent将名为config的输入对象传递给子节点,并侦听子节点发出的事件。

其中配置对象类型为

config:any = {
    a: number;
    b: number;
}

此处保持简单config.a由子管理,因此父级永远不会更改它,同样config.b由父级管理。

我在设置此通信模型时观察到了以下奇怪的行为。

  1. 父通过属性绑定传递所需的输入,即
  2.   

    [配置] = “配置”

    通常属性绑定只能以一种方式工作,但这里它的行为是双向绑定。即,当父母在其自己的范围内更新config.b时,孩子的配置也会更新,反之亦然。

    1. child希望收到父对其自己的配置对象所做的任何更改的通知,因此它实现了OnChanges生命周期钩子,以执行一些内部功能。但是因为正在改变的对象本质上是不可变的,所以除非将孩子通知,否则不会通知孩子,

      • 它更新配置对象引用,如

        this.config = new Config()
        
      • 或使用onPush更改检测策略并调用以下函数通知孩子有关更改的信息。

        changeDetectorRef.markForCheck()
        
    2. 但是当我尝试changeDetectorRef.markForCheck()时 永远不会触发孩子的ngOnChanges生命周期钩子。

      任何人都可以解释这两个奇怪问题背后的原因。我在this plunker中复制了这两个问题以供参考。

1 个答案:

答案 0 :(得分:2)

基本上,Angular只会做一个“脏”的事情。校验。意味着没有正确检查复杂对象。

以下是有人更好地解释它的链接:https://stackoverflow.com/a/34799257/9097714

另一个解决方案是创建一个EventEmitter,您可以绑定并手动告诉父< - >孩子发生了变化。

例如:

@Output() onChange: EventEmitter<any> = new EventEmitter<any>();

public triggerChanges() {
   this.onChange.emit()
}

然后在模板文件中:

<app-my-component (onChange)="event"></app-my-component>

希望这有帮助!

修改https://plnkr.co/edit/9V3vS8S8LSESHNqKSay8?p=preview我在这里添加了ngDoCheck,唯一的缺点就是如果真的要重新分配值,你必须进行比较。