简体   繁体   English

valueChanges in Array 反应式 forms

[英]valueChanges in Array reactive forms

I have a reactive form that contains an Array of objects with 2 fields.我有一个反应形式,其中包含一个具有 2 个字段的对象数组。 I am trying to do a simple multiplication between those two fields whose result will be stored in a third field.我正在尝试在这两个字段之间进行简单的乘法运算,其结果将存储在第三个字段中。 I subscribed with valueChanges to the changes of the Array and it works, but the values of the form does not listen to those changes.我用valueChanges订阅了 Array 的更改并且它可以工作,但是表单的值不会听这些更改。

Here's an example in Stackblitz: https://stackblitz.com/edit/angular-ivy-qr2bg3?file=src/app/app.component.ts这是 Stackblitz 中的一个示例: https://stackblitz.com/edit/angular-ivy-qr2bg3?file=src/app/app.component.ts

在此处输入图像描述

What is the correct way to subscribe to changes in an Array containing objects?订阅包含对象的数组中的更改的正确方法是什么?

formDoyle: FormGroup;
  largo: number;
  resultPiesTablares = 0;

  constructor( private fb: FormBuilder ) { }

  ngOnInit(): void {

    this.formDoyle = this.fb.group({
      calculos: this.fb.array([
        this.getCalculo()
      ])
    });

    this.formDoyle.get('calculos')?.valueChanges.subscribe(res => {
      const control = <FormArray>this.formDoyle.controls['calculos'];
      this.resultPiesTablares = 0;
      for (let i in res) {
        let diametroMenor = res[i].diametroMenor;
        let largo = res[i].largo;
        let resultPiesTablares = diametroMenor * largo;
        control.at(+i).get('subTotal')?.setValue(resultPiesTablares, { onlySelf: true });
      }
    });
    
  }

  private getCalculo() {
    const numberPatern = '^[0-9.,]+$';
    return this.fb.group({
      diametroMenor: ['', [Validators.required, Validators.pattern(numberPatern)]],
      largo: ['', [Validators.required, Validators.pattern(numberPatern)]],
      subTotal: ['']
    });
  }

  agregarCalculo() {
    const control = <FormArray>this.formDoyle.controls['calculos'];
    control.push(this.getCalculo());
  }

   removeCalculo(i: number) {
    const control = <FormArray>this.formDoyle.controls['calculos'];
    control.removeAt(i);
  }

You are not getting the new value of subTotal in your valueChanges listener because you put { onlySelf: true } which is a good thing because otherwise you would get an infinite loop.您没有在 valueChanges 侦听器中获得 subTotal 的新值,因为您放置了{ onlySelf: true }这是一件好事,否则您将获得无限循环。

If you want to listen to the subTotal you need to subscribe to it:如果您想收听 subTotal,您需要订阅它:

control.at(0).get('subTotal').valueChanges.subscribe(res => {

        console.log('subTotal:', res)

});

In the end what worked for me was to subscribe to the changes of each value:最后对我有用的是订阅每个值的更改:

See updated stackblitz: https://stackblitz.com/edit/angular-ivy-qr2bg3?file=src/app/app.component.ts查看更新的 stackblitz: https://stackblitz.com/edit/angular-ivy-qr2bg3?file=src/app/app.component.ts

for (let i in calculos) {
    control.at(+i).get('diametroMenor')?.valueChanges.subscribe( res => {
      let resultPiesTablares = res * calculos[i].largo;
      control.at(+i).get('subTotal')?.setValue(resultPiesTablares, { onlySelf: true });
    });

    control.at(+i).get('largo')?.valueChanges.subscribe( res => {
      let resultPiesTablares = calculos[i].diametroMenor * res;
      control.at(+i).get('subTotal')?.setValue(resultPiesTablares, { onlySelf: true });
    });
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM