我想在编辑模式下工作时检测反应式表单上的更改。 我尝试使用 valueChanges,但问题是当我加载已提交的表单进行编辑时,它会触发每个预填充控件的事件。 虽然我的要求是仅在用户对表单进行任何更改时触发。 任何人都可以建议
尝试在ngAfterViewInit()
方法中订阅valueChanges
。
export class MyComponent implements AfterViewInit {
ngAfterViewInit() {
this.myForm.controls['name'].valueChanges.subscribe(change => {
console.log(change);
});
}
...
使用valueChanges
对您来说是一种正确的方法。
我假设您正在使用setValue
或patchValue
来设置预填充值。这两者都作为可选emitEvent
属性。如果将其设置为false
,则不会触发valueChanges
。所以。。。。设置预填充值时,请使用:
this.form.setValue({ test: "test" }, { emitEvent: false });
此操作现在不会触发valueChanges
。
所有FormControl
对象都有诸如markAsUntouched()
或markAsPristine()
之类的方法,因此,根据@uminder所指示的内容,要将整个表单设置为pristine
在ngAfterViewInit
触发器之后或直接在表单初始化后,您可以简单地遍历所有FormControl
对象并将它们设置为"原始"?根据定义,用户此后的任何更改都会触发窗体或控件的valueChanges
?
在将所有项目设置为touched
(以触发验证设置)的递归方法下方FormControl
您可以将其用于control.markAsUntouched
或control.markAsPristine
?
export function markFormGroupTouched(formGroup: FormGroup): void {
const fa = new FormArray([]).constructor.name;
Object.values(formGroup.controls).forEach((control: any, i) => {
if (control.constructor.name === fa) {
control.controls.forEach((ctrl: any) => markFormGroupTouched(ctrl));
}
else{
control.markAsTouched();
}
});
}
这些函数对于FormArray
是递归的,因此它将遍历整个 form.controls 树。
注意:
const fa = new FormArray([]).constructor.name;
是避免 代码缩小的问题。因为typeof FormArray
回来FormGroup
你必须在控件上进行比较 构造函数,但FormArray
的工厂在 缩小,因此不能对..=="FormArray"
进行硬编码,因为缩小时该名称不是构造函数名称。这种方法允许这种意外情况。