基于Rebox格式的Checkbox计算

时间:2018-03-17 05:51:04

标签: angular angular-reactive-forms angular-forms reactive-forms

我对如何获得复选框值感到困惑,所以我得到了"金额"和"总计"值。计算非常简单。复选框值为1.20或20%。如果复选框值对其进行检查,则金额为(数量*价格)/复选框值。总价值仅为(数量*价格)。这是我的代码的链接。

UPDATE !!!现在它正在运行,但问题是它没有自动计算,但我必须在输入字段外单击才能更新它。

COMPLETE CODE IS HERE

 onChange(isChecked, id){
    console.log(isChecked)
    let quantity = (<FormArray>this.myForm.controls['rows']).controls[id]['controls']['quantity'].value
    let price = (<FormArray>this.myForm.controls['rows']).controls[id]['controls']['price'].value
    let checkbox = (<FormArray>this.myForm.controls['rows']).controls[id]['controls']['checkbox'].value

    let x = (<FormArray>this.myForm.controls['rows']).at(id);
    if(isChecked){
      x.patchValue({
        amount: (quantity * price)/checkbox,
        total: quantity * price
    });
    }

    else {
      x.patchValue({
        amount: (quantity * price)/checkbox,
        total: (quantity * price)/checkbox,
    });
    }
  }

2 个答案:

答案 0 :(得分:1)

抱歉延迟了。我想使用“辅助变量”“总计”你必须

//declare the variable at first
totals:any[]=[] //totals will be like, e.g. [{total:0,amount:0},{total:10,amount:23}...]

//In patchValues
    this.orders.forEach(material => {
      material.materials.forEach(x => {
        rows.push(this.fb.group({
          material_id: x.id,
          material_name: x.name,
          quantity: [null, Validators.required],
          price: [null, Validators.required],
          dis_checkbox: [true],
          checkbox: [1.20]
        })) //see that total and amount is NOT in the form
        this.totals.push({amount:0,total:0});  //<--add this line
      })
    })

//And finally, we change the "setOnchange" (I commented the lines that you don't need)
setOnChange()
{
    const formarray=this.myForm.get('rows') as FormArray;
    for (let i=0;i<formarray.length;i++)
    { 
      formarray.at(i).valueChanges.subscribe(val=>{

      //"total" and "amount" are simply variables
      //we needn't look for the controls (not exist)
//      let controlTotal=(this.myForm.get('rows') as FormArray).at(i).get('total')
//      let controlAmount=(this.myForm.get('rows') as FormArray).at(i).get('amount')     

      let value=(val.quantity)*(val.price);
      this.totals[i].total=value;  //<--just update the value of the variable
//      if (controlTotal.value!=value)  
//        controlTotal.setValue(value);

      value=val.dis_checkbox?value/val.checkbox:value;
      this.totals[i].amount=value;  //<--idem
//      if (controlAmount.value!=value)  
//        controlAmount.setValue(value); 
    });
    }
  }

答案 1 :(得分:0)

Josep,当我们使用ReactiveForm时,我们通常会控制订阅AbstractControl.valuesChange的更改。

所以你的表单不需要(cange)也不需要(NgModel),只需

<form class="form-horizontal" [formGroup]="myForm" (ngSubmit)="onCreateProduct()" >
  <div class="card">
    <div class="card-block" formArrayName="rows">
      <table class="table">
   ...
        </thead>
        <tbody>
          <tr *ngFor="let row of myForm.controls.rows.controls; let i = index" [formGroupName]="i">
            <td>{{row.value.material_id}}</td>
            <td>{{row.value.material_name}}</td>
            <td><input class="col-md-6" type ="number" formControlName="quantity" ></td>
            <td><input class="col-md-6" type ="number" formControlName="price" ></td>
            <td><input type="checkbox" class="col-md-6" formControlName="dis_checkbox" > 20 %</td>
            <td><input class="col-md-6" formControlName="amount" readonly disabled ></td>
             <td><input class="col-md-6" formControlName="total" readonly disabled></td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</form>

然后我们在pathValues

之后控制代码中添加的“更改”
  patchValues() {
    let rows = this.myForm.get('rows') as FormArray;
    this.orders.forEach(material => {
...
    })
    setOnChange() //<--call a function
}
setOnChange()
{
    const formarray=this.myForm.get('rows') as FormArray;
    for (let i=0;i<rows.length;i++)
    { 
      formarray.at(i).valueChanges.subscribe(val=>{
      //see that in val we have all the values
      //val.quantity,val.price,val.dis_checkbox...

      //I use an auxiliar variables to get the controls "total" and "amount"
      let controlTotal=(this.myForm.get('rows') as FormArray).at(i).get('total')
      let controlAmount=(this.myForm.get('rows') as FormArray).at(i).get('amount')     

      let value=(val.quantity)*(val.price);

      if (controlTotal.value!=value)  //Only when the values are not equal
        controlTotal.setValue(value);

      value=val.dis_checkbox?value/val.checkbox:value;
      if (controlAmount.value!=value)  //Only when the values are not equal
        controlAmount.setValue(value); 
    });
    }
  }

当我们使用valueChanges时,我们可以订阅uniq控件,formArray(mychoice)的一行或所有表单。 好吧,代码还没完成。通常如果我们有“计算字段”(在这种情况下“总计”和“金额”)我们不需要使这些字段属于表格。为什么不使用对象数组(egtotals = [{total:0,ammount:0} {total:0,ammount:0} ..]并更改/显示值?

<tr *ngFor="let row of myForm.controls.rows.controls; let i = index" [formGroupName]="i">
             ...
            <td><input class="col-md-6" type ="number" formControlName="quantity" ></td>
            <td><input class="col-md-6" type ="number" formControlName="price" ></td>
            <td><input type="checkbox" class="col-md-6" formControlName="dis_checkbox" > 20 %</td>
  <!--see that don't belong to the form, I use the variable "totals"-->
            <td><input class="col-md-6" [value]="totals[i].amount" readonly disabled ></td>
             <td><input class="col-md-6" [value]="totals[i].amount" readonly disabled></td>
          </tr>