使用Angular FormArray计算值 [英] Calculated values using Angular FormArray

查看:240
本文介绍了使用Angular FormArray计算值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据FormArray中的特定值计算总值或其他值.

I'm attempting to calculate a total or other value based on a particular value in a FormArray.

我发现在订阅valueChanges并尝试将整个数组传递给类似reduce之类的东西时,父FormGroup上不存在新值".

I'm finding that when subscribing to valueChanges and attempting to pass the whole array to something like reduce, the "new value" isn't present on the parent FormGroup.

StackBlitz上的原始示例

示例:

this.frm.get('arr')['controls'][i].valueChanges
  .subscribe((newVal) => {
    this.frm.get('total').patchValue(
      this.frm.get('arr').value.reduce((acc, curr) => {
        return acc + curr.v;
      }, 0)
    )
  });

如果arr的值是[0, 1, 2, 3, 4],并且我将第一个值更改为1,我仍然会得到10而不是11.

If arr has values [0, 1, 2, 3, 4] and I change the first value to 1, I still get 10 instead of 11.

this.frm.get('arr').value显示所有初始值,而不显示更新后的值.

this.frm.get('arr').value shows all the initial values and not the updated values.

我对Reactive Forms还是很陌生,所以我确定我只是在这里缺少一些基本知识.

I'm fairly new to Reactive Forms so I'm sure I'm just missing something fundamental here.

更新(有解决方案,但我仍然缺乏理解):

UPDATE (Have a solution, but I'm still lacking understanding):

我真的很想知道为什么我不能像Eliseo所建议的那样订阅整个阵列的更改.

I'd really love to know why I'm not able to subscribe to changes to the whole array like Eliseo had suggested.

我也想知道为什么我使用.value的地方之间会有这样的差异-如果要通过模型驱动整个反应式表单,然后将frm.value传递给您的Submit函数,那么为什么.value在整个表单层次结构中是如此不一致吗?

I'm also interested in why there is such a difference between where I use .value - If the whole point of Reactive Forms are to be Model Driven and then pass frm.value to your Submit function, then why is .value so inconsistent throughout the form hierarchy?

更新2

更新了StackBlitz解决方案在Eliseo更新后得到他的指导

我找到了一个很好的解决方案.它不会在任何地方使用controls,而且感觉很干净. Eliseo的建议方法迫使我尝试一下.我相信重要的是强制转换为FormArray并在其上执行任何push.这样会使parent字段与FormGroupFormArray的其余部分保持联系,因此它仍包含在valueChanges事件中.

I've found a solution that I feel pretty good about. It doesn't use controls anywhere and feels very clean. Eliseo's suggested approach pushed me to try this out. I believe the important thing is casting to a FormArray and executing any push on that. This keeps the parent field tied to the rest of your FormGroup or FormArray thus it stays included in the valueChanges event.

我现在认为使用controls是Angular Reactive Forms的反模式,但是我需要搜索有关该主题的更多指南.

I now believe using controls is an anti-pattern to Angular Reactive Forms, but I need to search for more guidance on that topic.

推荐答案

为什么不侦听所有数组的更改并使用newValues进行总计?

why not listen changes of all array and make total with newValues?

 //NOT ['controls'][i]
this.frm.get('arr')['controls'].valueChanges
  .subscribe((newVal) => {
    this.frm.get('total').patchValue(
      //use newVal
      newVal.reduce((acc, curr) => {
        return acc + curr.v;
      }, 0)
    )
  });

那是行不通的,为此请更改buildForm的代码:

That's not work, Change the code of buildForm for this:

buildForm() {
    let controls:any[]=[];
    for (let i:number = 0; i < 5; ++i) {
      controls.push(this.builder.group({
        v: i
      }))
    this.frm = this.builder.group({
      total: [{value: '', disabled: true}],
      arr: this.builder.array(controls)
    });
      this.frm.get('arr').valueChanges
      .subscribe((newVal) => {
        let total:number=0;
        newVal.forEach(e=>{
          total=total+parseInt(e.v)});

        this.frm.get('total').patchValue(total,0)

      });
    }
  }

主要更改是forEach而不是reduce的使用,parseInt的使用以及formArray的制作方法.

The main changes is use forEach and not reduce, the use of parseInt, and the way to make the formArray.

这篇关于使用Angular FormArray计算值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆