我有一个父组件,它有两个模板(Stackblitz):
-
第一个包含一个简单的数据绑定文本
-
第二个包含更新数据模型的子组件(来自本演示中的
constructor
和ngOnInit
)
这是父组件模板:
<ng-template [ngIf]="true">
<div>
<b>Value from TemplateComponent: </b>{{ dataService.value | async }}
</div>
</ng-template>
<ng-template [ngIf]="true">
<template-component></template-component>
</ng-template>
父组件和子组件都是 ChangeDetectionStrategy.OnPush
,这是一项要求 .
问题是从子组件的 ngOnInit
(以及之后的那些)开始的数据更新不会被父组件中的更改检测所拾取 . 这会导致演示中的父组件显示:
TemplateComponent的值:构造函数的值
代替
TemplateComponent的值:来自ngOnInit的值
因为CD仅在构造函数阶段获取更新,但不在 ngOnInit
及更高版本中:
export class TemplateComponent implements OnInit {
public constructor(public readonly dataService: DataService) {
this.dataService.setValue("value from constructor");
}
public ngOnInit(): void {
// This update is NOT picked up by CD in parent component
this.dataService.setValue("value from ngOnInit");
}
}
除了 markForCheck()
的这种方法之外,我还在孩子中尝试了一个简单的 @Output
事件,但它显然不起作用,因为子项是通过 ng-template
创建的,实际上并不是父组件的直接子项 .
有人会想知道什么是最干净的和Angular的 OnPush
友好的方法,用于从 ng-template
创建控件将数据传递给父级?
P.S.: 由
最干净和Angular的OnPush友好方法
,我的意思是保持所有部分(组件和服务松散耦合)的东西,例如,不涉及 setTimeout()
或其他脏修复 .