我有两个组成部分;父母和孩子,通过@Input
和@Output
属性装饰者进行通信。即,Parent将名为config
的输入对象传递给子节点,并侦听子节点发出的事件。
其中配置对象类型为
config:any = {
a: number;
b: number;
}
此处保持简单config.a
由子管理,因此父级永远不会更改它,同样config.b
由父级管理。
我在设置此通信模型时观察到了以下奇怪的行为。
[配置] = “配置”
通常属性绑定只能以一种方式工作,但这里它的行为是双向绑定。即,当父母在其自己的范围内更新config.b
时,孩子的配置也会更新,反之亦然。
child希望收到父对其自己的配置对象所做的任何更改的通知,因此它实现了OnChanges
生命周期钩子,以执行一些内部功能。但是因为正在改变的对象本质上是不可变的,所以除非将孩子通知,否则不会通知孩子,
它更新配置对象引用,如
this.config = new Config()
或使用onPush
更改检测策略并调用以下函数通知孩子有关更改的信息。
changeDetectorRef.markForCheck()
但是当我尝试changeDetectorRef.markForCheck()
时
永远不会触发孩子的ngOnChanges
生命周期钩子。
任何人都可以解释这两个奇怪问题背后的原因。我在this plunker中复制了这两个问题以供参考。
答案 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,唯一的缺点就是如果真的要重新分配值,你必须进行比较。