Javascript 如何获取值以角度反应形式更改的字段的FormControlName
我有一个带有10多个表单控件的反应式表单,并使用对valueChanges的订阅来检测更改。它工作正常,但输出始终是整个表单值对象(表示所有表单控件及其值)。是否有一种方法可以简单地获取更改字段的表单控件名称Javascript 如何获取值以角度反应形式更改的字段的FormControlName,javascript,angular,typescript,rxjs,Javascript,Angular,Typescript,Rxjs,我有一个带有10多个表单控件的反应式表单,并使用对valueChanges的订阅来检测更改。它工作正常,但输出始终是整个表单值对象(表示所有表单控件及其值)。是否有一种方法可以简单地获取更改字段的表单控件名称 this.form = this.fb.group({ field1: ['', Validators.required], field2: ['', Validators.required], field3: ['', Validators.required],
this.form = this.fb.group({
field1: ['', Validators.required],
field2: ['', Validators.required],
field3: ['', Validators.required],
field4: ['', Validators.required],
field5: ['', Validators.required],
field6: ['', Validators.required],
field7: ['', Validators.required],
field8: ['', Validators.required],
field9: ['', Validators.required],
field10: ['', Validators.required],
field11: ['', Validators.required],
field12: ['', Validators.required],
field13: [{ value: '', disabled: true }, Validators.required]
});
this.form.valueChanges.subscribe(
result => this.calculateParams(result)
);
calculateParams(result) {
console.log(result); // giving the entire form.value object
}
您可以使用
get
方法和访问valueChanges
方法将formcontrol与formgroup隔离
this.form.get('formcontrolName').valueChanges()
注意:
form.get
返回AbstractControl
,该控件上还包含valueChanges
方法。尚未完全测试代码,但想法是将控件与其键配对,然后同时在每个控件上侦听valueChanges
,并返回对象键而不是值(当然,您可以将值和键映射到输出)
这是一个解决办法,但如果存储旧值,您可以执行类似的操作
this.old={...this.myForm.value}
this.myForm.valueChanges.subscribe(res=>{
const key=Object.keys(res).find(k=>res[k]!=this.old[k])
this.old={...this.myForm.value}
})
您可以单独订阅每个更改
for (const controlProperty in this.myForm.controls) {
if (this.myForm.controls.hasOwnProperty(controlProperty)) {
this.myForm.controls[controlProperty].valueChanges.pipe(untilDestroyed(this)).subscribe(result => {
console.log(controlProperty + " is now ", result);
});
}
}
对我来说,这感觉更加棱角分明。Eliseo的rxjs方式
将控件动态添加到
FormGroup
后,对每个控件使用valueChanges
const ct = {key: 'myControl'};
this.myForm.addControl(ct.key, new FormControl('', Validators.required))
this.myForm.controls[ct.key].valueChanges
.subscribe(d => {
// here ct will be available as closure , so that we can access every form control here and do operation accordingly
console.log(d, ct.key);
})
这里,
ct
对象将作为一个闭包在subscribe中提供。对,但是为了订阅所有值,我必须分别订阅其中的每个值(对于每个表单控件)我想避免这种情况,因为我会有更多字段的表单。您可以提取fb.group
的配置,这样您就可以在表单上使用Object.keys
,并订阅forEach中的每个字段loop@dimitri你能试试这个this.form.valueChanges().pipe(map(form=>form.controls),过滤器吗(control=>control.dirty)).subscribe()
;@PhuNgo单个组件上的那么多订阅(例如50+)在某一点上不是内存瓶颈吗?@KiraAG-没有得到任何结果(无法读取未定义的属性“dirty”
).这里的思路是什么?这似乎起到了作用。我最初认为类似的东西,但希望有一个“更圆滑”的解决方案..谢谢!在Angular 6和Angular 7中,myform.get(“…”).value和“res”,或者res和myform.value[…])之间有一个不同之处(我想你也可以订阅(res,old)=>{..}但是在Angular 8中看起来没有区别。我真的不知道是否有更好的解决方案这似乎是一个很好的解决方案。但是,第一次触发它时,尽管有startWith
,它总是会为我返回窗体的第一个控件,不管哪个控件实际发生了更改。第二次之后,它会工作好吧,我很困惑,因为即使是第一次,如果我比较oldValues和newValues,唯一的区别就是控件实际上改变了它的值。
this.form.valueChanges.pipe(
startWith(this.form.value),
pairwise(),
map(([oldValues, newValues]) => {
return Object.keys(newValues).find(k => newValues[k] != oldValues[k]);
}),
).subscribe(key => {
console.log( key )
});
const ct = {key: 'myControl'};
this.myForm.addControl(ct.key, new FormControl('', Validators.required))
this.myForm.controls[ct.key].valueChanges
.subscribe(d => {
// here ct will be available as closure , so that we can access every form control here and do operation accordingly
console.log(d, ct.key);
})