Angular 使用反应式表单和ChangeDetectionStrategy.OnPush显示验证消息

Angular 使用反应式表单和ChangeDetectionStrategy.OnPush显示验证消息,angular,angular-reactive-forms,angular2-changedetection,reactive-forms,angular-changedetection,Angular,Angular Reactive Forms,Angular2 Changedetection,Reactive Forms,Angular Changedetection,我正在尝试将应用程序迁移到使用ChangeDetectionStrategy.OnPush。然而,我在尝试使用一些反应形式时遇到了一些阻碍因素 我有一个可重用的控件,它根据一些状态标志显示验证消息(例如*ngIf=“control.toucted&&control.invalid”)。我遇到的问题是,无法检测触摸的标志何时更改,因此无法使用ChangeDetectorRef触发更改检测 可以通过监听click事件来引用输入元素本身,但这并不说明何时使用markAsTouched(),传递对元素本

我正在尝试将应用程序迁移到使用
ChangeDetectionStrategy.OnPush
。然而,我在尝试使用一些反应形式时遇到了一些阻碍因素

我有一个可重用的控件,它根据一些状态标志显示验证消息(例如
*ngIf=“control.toucted&&control.invalid”
)。我遇到的问题是,无法检测触摸的
标志何时更改,因此无法使用
ChangeDetectorRef
触发更改检测

可以通过监听
click
事件来引用输入元素本身,但这并不说明何时使用
markAsTouched()
,传递对元素本身的引用并不总是可能的,而且总是不雅观的


是否有一种方法可以使用
OnPush
并仍然对表单控制状态做出响应(例如,
toucted
),或者这只是一种普遍的痛苦?

我不知道您是否正在寻找直接使用新表单组创建反应表单的新方法。对不起,如果我不明白你的问题。e、 g

//before
this.myForm=this.formBuilder({
   control1:''
   })
//after
this.myForm=new FormGroup({
   control1:new FormControl(''),
},{ updateOn: 'blur' })

您可以侦听状态更改,然后调用
markForCheck()
更新视图:

构造函数(changeDetectorRef:changeDetectorRef){
this.formGroup.statusChanges.subscribe(status=>changeDetectorRef.markForCheck());
}
更新: 由于我无法发表评论,我将更新此答案

关于状态更改,您是对的。当然,您需要订阅statusChanges,这是一个错误

我想我们错过了一点。在
CheckOnce
模式(OnPush)下,Angular将检查DOM事件(包括模糊)后的更改,因此视图应该更新,您遇到的消息(
*ngIf=“control.toucted&&control.invalid”
)应该可以工作

但是如果在中调用
markAsTouched()
,则在调用
markForCheck()
之前,代码不会检查更改


这里有一个工作示例:

很多备选方案:@pixelbits-这基本上只是一个如何使用OnPush的演练。编辑我的问题以澄清我的主要问题。你找到解决方案了吗?@miladfm不太清楚。归根结底,除非Angular得到更新,为那些状态变化添加可观测值,否则没有一种很好的方法可以将
OnPush
用于反应式表单组件。最后,我使用默认策略将组件保留在表单中,然后对其他所有内容使用
OnPush
。不完全是-我特别遇到的问题是基于“touch”属性更改触发更新。例如,当父组件在控件上调用“markAsTouched”时。
statusChanges
仅处理控件的验证状态(有效/无效/脏/原始),并且由于
被触摸而不发射。另外,FWIW,您的语法不正确;)
statusChanges
是可观察的,因此您需要对其调用
。subscribe
,而不仅仅是向其传递回调。