我正在尝试构建Angular反应形式,其中输入字段值根据其他字段中的输入进行更新。假设三个输入字段amount
,price
和total
反映了变化,因此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);
}
}
答案 0 :(得分:2)
this.orderForm.value
是只读的。那么您可以尝试执行以下操作
this.orderForm.controls['total'].setValue(price/ this.orderForm.value.amount);
答案 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.value
或this.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
})