我有一个父组件,其中有两个模板(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
创建的控件传递给父级的想法吗?
PS:通过
Angular最
OnPush
最友好的方法
,我的意思是保持所有部分(组件和服务松散耦合)的东西,例如,不涉及setTimeout()
或其他肮脏的修复程序。