角反应式形成两种方式的数据绑定

时间:2019-03-26 23:04:17

标签: javascript angular

我正在尝试构建Angular反应形式,其中输入字段值根据其他字段中的输入进行更新。假设三个输入字段amountpricetotal反映了变化,因此amount * price = total成立。完整代码https://stackblitz.com/edit/angular-e7rnxf

import {
  Component,
  Input
} from '@angular/core';
import {
  FormBuilder
} from '@angular/forms';
@Component({
  selector: 'hello',
  template: `
  <form [formGroup]="orderForm" (ngSubmit)="onSubmit()">  
    Amount: <input (keyup)="onAmountChange($event)" formControlName="amount">{{ orderForm.value.amount }}<br>
    Price: <input (keyup)="onPriceChange($event)" formControlName="price">{{ orderForm.value.price }}<br>
    Total: <input (keyup)="onTotalChange($event)" formControlName="total"> {{ orderForm.value.total }}<br>
    <button type="submit">Submit</button>
 </form>
  `
})
export class HelloComponent {
  constructor(private fb: FormBuilder) {}
  orderForm = this.fb.group({
    amount: 200,
    price: 95,
    total: ''
  });
  onTotalChange(e) {
    const total = e.currentTarget.value;
    this.orderForm.value.amount = total / this.orderForm.value.price;
  }
  onAmountChange(e) {
    const amount = e.currentTarget.value;
    this.orderForm.value.total = this.orderForm.value.amount * this.orderForm.value.price;
  }
  onPriceChange(e) {
    const price = e.currentTarget.value;
    this.orderForm.value.total = price * this.orderForm.value.amount;
  }
  onSubmit() {
    console.log(this.orderForm.value);
  }
}

4 个答案:

答案 0 :(得分:2)

this.orderForm.value是只读的。那么您可以尝试执行以下操作

this.orderForm.controls['total'].setValue(price/ this.orderForm.value.amount);

stackblitz example modified

答案 1 :(得分:2)

我不确定如何派生stackblitz,但是如果用以下内容替换您的课程,则会得到正确的结果。

import { FormBuilder, FormGroup } from '@angular/forms';


export class HelloComponent implements OnInit  {
  constructor(private fb: FormBuilder) {}

  public orderForm: FormGroup;

  public ngOnInit(): void
  {
    this.orderForm = this.fb.group({
      amount: 200,
      price: 95,
      total: ''
    });
  }

  onSubmit() {
    const amount = this.orderForm.controls.amount.value;
    const price = this.orderForm.controls.price.value;

    this.orderForm.controls.total.setValue(amount * price);
  }
}

这将为您提供提交的总数,以使值像其他输入一样改变,您可以重新添加功能,但现在改为使用this.orderForm。对输入字段之一进行更改时,可以使用this.orderForm.controls.price.valuethis.orderForm.controls.price.value检查其值。或者,您可以console.log(this.orderForm.value);来获取所有三个值作为一个对象。看起来像{amount: 200, price: "97", total: 19400}

答案 2 :(得分:1)

为什么用反应性垃圾使事情复杂化,只需使用模板表格即可。

import {
  Component,
  Input
} from '@angular/core';

@Component({
  selector: 'hello',
  template: `
  <form (ngSubmit)="onSubmit()">  
    Amount: <input (keyup)="onAmountChange($event)" name="amount" [(ngModel)]="amount">{{ orderForm.value.amount }}<br>
    Price: <input (keyup)="onPriceChange($event)" name="price" [(ngModel)]="price">{{ orderForm.value.price }}<br>
    Total: <input (keyup)="onTotalChange($event)" name="total" [(ngModel)]="total"> {{ orderForm.value.total }}<br>
    <button type="submit">Submit</button>
 </form>
  `
})
export class HelloComponent {
  constructor() {}
  amount = 200;
  price = 95;
  total = '';
  onTotalChange(e) {
    const total = e.currentTarget.value;
    this.amount = total / this.price;
  }
  onAmountChange(e) {
    const amount = e.currentTarget.value;
    this.total = this.amount * this.price;
  }
  onPriceChange(e) {
    const price = e.currentTarget.value;
    this.total = price * this.amount;
  }
  onSubmit() {
    
  }
}

答案 3 :(得分:1)

我注意到上述答案提供了使用setValue的解决方案,在这种情况下,这已经足够了。但是,我希望您知道您也可以使用patchValue

例如,如果您只想更新反应形式上的total(而不是其他FormControl)的值,则可以通过执行以下操作来简单地实现:

this.orderForm.patchValue({
  total: price * this.amount
});

如您所见,语法更简单,更直观。另一方面,如果您尝试使用setValue实现此目的,则必须显式链接它,或者 由于setValue的局限性以及该方法的工作方式,您必须更新所有FormControl。如果您不提供所有的FormControl,它将引发错误。这可能不是一件坏事,因为它“更安全”。

this.orderForm.setValue({
  amount: 200,
  price: 95,
  total: price * this.amount
})