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

问题描述 投票:0回答:3

我正在尝试将应用程序迁移为使用

ChangeDetectionStrategy.OnPush
。然而,我在尝试使用一些反应形式时遇到了一些阻碍。

我有一个可重用的控件,可以根据某些状态标志(例如

*ngIf="control.touched && control.invalid"
)显示验证消息。我遇到的问题是,无法检测
touched
标志何时更改,因此无法使用
ChangeDetectorRef
触发更改检测。

可以通过监听 click 事件来引用输入元素本身来完成,但这并不能说明何时使用

markAsTouched()
,并且并不总是传递对元素的引用可能,但总是不优雅。

有没有办法使用

OnPush

并仍然响应表单控件状态(例如

touched
),或者只是普遍痛苦?
    

angular angular2-changedetection angular-reactive-forms angular-changedetection
3个回答
1
投票
markForCheck()

来更新视图:


constructor(changeDetectorRef: ChangeDetectorRef) { this.formGroup.statusChanges.subscribe(status => changeDetectorRef.markForCheck()); }

更新:
由于我无法发表评论,我将更新此答案。

您对 statusChanges 的看法是正确的。当然你需要订阅 statusChanges,这是一个错误。

我认为我们在这里忽略了一点。在

CheckOnce

模式(OnPush)下,Angular 将在 DOM 事件(包括模糊)之后检查更改,因此视图应该更新并且您提到的消息 (

*ngIf="control.touched && control.invalid"
) 应该起作用。

但是如果您在代码中调用

markAsTouched()

,则在您调用

markForCheck()
之前不会检查更改。

这是一个工作示例:

https://stackblitz.com/edit/angular-6-reactive-form-validation-touched-sjhijt


0
投票

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



0
投票
markAsTouched

的方法覆盖控件的原始

markForCheck
方法:
const originalMarkAsTouched = this.control.markAsTouched;
this.control.markAsTouched = () => {
  originalMarkAsTouched.call(this.control);
  this.changeDetectorRef.markForCheck();
};

© www.soinside.com 2019 - 2024. All rights reserved.