【问题标题】:Angular ReactiveForms not getting dynamic valueAngular ReactiveForms 没有获得动态价值
【发布时间】:2018-08-02 03:07:44
【问题描述】:

我在 Angular 中使用反应式表单,并且我有这个 FormArray,我可以从中获取除 product_total 之外的所有值。

<tbody formArrayName="products">
  <tr *ngFor="let phone of productForms.controls; let i=index" [formGroupName]="i">
      <th scope="row">{{i+1}}</th>
      <td><input type="text" class="form-control" placeholder="Product Code" formControlName="product_code"></td>
      <td><input type="text" class="form-control" placeholder="Product Name" formControlName="product_name"></td>
      <td><input type="number" class="form-control" placeholder="Price" formControlName="product_price" #price></td>
      <td><input type="number" class="form-control"  formControlName="product_quantity" value="1" #quantity></td>
      <td><input type="number" class="form-control" value="{{(price.value || 0) * (quantity.value || 1)}}" formControlName="product_total" disabled></td>
    </tr>
  </tbody>

如何为打字稿代码中的每个表单组获取product_total 值? 附言我在 HTML 代码中获取值,但不是在打字稿代码中

打字稿代码是:

constructor(private fb: FormBuilder) { }

ngOnInit() {
const product = this.fb.group({
  product_code: [],
  product_name: [],
  product_price: [],
  product_quantity: [1],
  product_total: []
});

this.myForm = this.fb.group({
  customer_name: '',
  customer_phone: '',
  customer_address: '',
  products: this.fb.array([product]),
  subtotal: Number,
  discount: Number,
  cgst: Number,
  sgst: Number,
  total_price: Number,
});
}

get productForms() {
  return this.myForm.get('products') as FormArray;
}


async submitForm() {
    const myForm = this.myForm.value;
    this.invoice = {
      products: myForm.products,
    };
    console.log(this.invoice.products);

  }

【问题讨论】:

  • 如果你想要全部,你必须订阅 valueChanges,见 e.g. alligator.io/angular/reactive-forms-valuechanges。如果仅按行总计使用 {{phone.get('product_price').value *( phone.get('product_quantity').value ||1)}}
  • @Eliseo 这不是我要问的。我在表单输入中得到 product_total 值,但在打字稿代码中没有。在打字稿代码中,我得到了空值。
  • 显示整行代码
  • @SurendraSinghChhabra,看看我的回答
  • @SurendraSinghChhabra 你能添加这个组件的打字稿吗?

标签: angular typescript angular-reactive-forms formarray


【解决方案1】:

已编辑,之前的代码有 {{ }},但如果我们使用 [value] 就不用放 {{ }},更新代码

你不必总属于formGroup

<input type="number" class="form-control" disabled
    [value]="phone.get('product_price').value *( phone.get('product_quantity').value)" >

如果您认为有必要,您可以在提交时制作地图

submit(form){
   if (form.valid)
   {
      let data={
             //all properties of for.value
             ...form.value,
             //but products was products "mappeated"
             products:form.value.products.map(v=>{
             return {
               //Which each product, return 
               ...v,   //all de properties of products +
               total:v.product_price*v.product_quantity  //total
          }})
        }

      console.log(data);
   }

【讨论】:

  • 映射正常,但未获取数组中的数据。即在控制台中获取数据但不在数组中
  • @SurendraSinghChhabra,对不起。我写了 [value]="{{...}}" 并且是 [value]="..." (未包含在 {{ }} 中)。我的想法是 formGroup 没有“总数”。如果我们需要 total 发送到 api 或其他什么,我们总是可以在提交表单中创建属性 total
  • 明白了!但仍然无法正常工作。请参阅我更新的打字稿代码以获取更多参考。此外 {...v,total:vproduct_priceproduct_quantity} 未定义,因为它在表单数组中,因此也会出错。
  • @SurendraSinghChhabra,尚未更新代码,抱​​歉耽搁了
  • 工作!!感谢您的努力。
【解决方案2】:

我有一个类似的逻辑要实现。我在控制器中使用了这样的东西:

ngOnInit() {
    this.formGroup = this.formBuilder.group({
        price: ['', [Validators.required]],
        quantity: ['', [Validators.required]],
        total: ''
    });

    this.formGroup.valueChanges.subscribe(change => {
        this.priceChanges()
    })
}

priceChanges() {
    let price = parseFloat(this.formGroup.value.price);
    let quantity = parseInt(this.formGroup.value.quantity);

    if (!isNaN(price) && !isNaN(quantity)) {
        let totalCost = (price * quantity).toFixed(2);
        this.formGroup.controls['total'].setValue(totalCost, { emitEvent: false })
    }
}

处理 FormArray 的编辑版本:

请注意在您的两个输入中添加的(ngModelChange)="detectValueChange(i)"

<tbody formArrayName="products">
    <tr *ngFor="let phone of productForms.controls; let i=index" [formGroupName]="i">
        <th scope="row">{{i+1}}</th>
        <td> <input type="text" class="form-control" placeholder="Product Code" formControlName="product_code"></td>
        <td> <input type="text" class="form-control" placeholder="Product Name" formControlName="product_name"></td>
        <td><input type="number" class="form-control" placeholder="Price" formControlName="product_price" #price (ngModelChange)="detectValueChange(i)"></td>
        <td><input type="number" class="form-control" formControlName="product_quantity" value="1" #quantity (ngModelChange)="detectValueChange(i)"></td>
        <td><input type="number" class="form-control" value="{{(price.value || 0) * (quantity.value || 1)}}" formControlName="product_total" disabled></td>
    </tr>
</tbody>

然后,类似于我原来的解决方案,但现在在 'products' 数组上进行索引

detectValueChange(index: number){
    let controls = this.formGroup.get('products') as FormArray;
    this.changeTotal(controls[index])
}

changeTotal(control) {
    let price = parseFloat(control.value.product_price);
    let quantity = parseInt(control.value.product_quantity);
    if (!isNaN(price) && !isNaN(quantity)) {
        let totalCost = (price * quantity).toFixed(2);
        control['product_total'].setValue(totalCost, { emitEvent: false })
    }
}

【讨论】:

  • 小心,1.- 你的函数 priceChanges 是错误的。您必须使用 this.formGroup.get('price').value,而不是 this.formGroup.value.price - 在控制台中查看差异。 2.- 当您将更改附加到表单中的所有更改时,当更改“总计”时,再次转到该功能
  • 你完全正确!我忘了加{ emitEvent: false },见编辑版。
  • 使用这种方法会导致只在第一个表单组而不是其他表单组中获取总数
  • @SurendraSinghChhabra 没有注意到 FormArray。请参阅我编辑的答案(未经测试!)。 toFixed 会给你一个字符串,所以可能想把它包装在 parseFloat 中。
  • @SurendraSinghChhabra 你也可以通过使用[formControlName] 来访问嵌套的FormControl。看到这个答案:stackoverflow.com/a/48151444/4632627
猜你喜欢
  • 2016-10-20
  • 2021-03-28
  • 2016-01-30
  • 2018-04-08
  • 2018-04-09
  • 2012-06-24
  • 1970-01-01
  • 2022-01-04
  • 2021-06-21
相关资源
最近更新 更多