Javascript 如何获取值以角度反应形式更改的字段的FormControlName

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],

我有一个带有10多个表单控件的反应式表单,并使用对valueChanges的订阅来检测更改。它工作正常,但输出始终是整个表单值对象(表示所有表单控件及其值)。是否有一种方法可以简单地获取更改字段的表单控件名称

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);
})