Angular8中自动计算的表单值未编辑时不被识别为有效数字如何解决
问题根因
你同时使用了formControlName和原生value属性绑定,Angular响应式表单的数据源是FormControl实例而非DOM元素的value属性,你在模板里绑定的计算值只更新了DOM显示,没有同步到FormControl的实际存储值。手动修改输入框时,输入事件会触发FormControl自动更新值,所以提交正常;自动计算的场景下没有触发FormControl值更新,哪怕修改dirty/touched状态也只是改了校验状态,不会同步实际值,所以提交的还是初始空值。
解决方法
方案1:表单值变动时自动同步计算结果(推荐)
监听表单中会影响总金额的字段(商品数量、单价)的变化,计算完成后直接更新value和vatValue对应的FormControl值:
首先修改模板,删除两个计算字段的value属性绑定,值完全由FormControl控制:
<input formControlName="name" placeholder="prod name" required> <input formControlName="price" placeholder="prod quantity" required> <input type="number" formControlName="value"> <input type="number" formControlName="vatValue">
在组件初始化阶段添加值变动监听逻辑:
ngOnInit() { // 监听商品列表的数值变动,自动同步总金额 this.invoicePositions.valueChanges.subscribe(() => { this.updateTotalValues(); }); // 初始化时计算一次默认值 this.updateTotalValues(); } updateTotalValues() { this.positions = this.invoicePositions.value; let tempValue = 0; for (const productValue of this.positions) { tempValue += productValue.quantity * productValue.product.price; } this.invoiceTotal = tempValue; // 直接更新表单控件的存储值 this.invoiceForm.controls.value.setValue(tempValue * 1.19); this.invoiceForm.controls.vatValue.setValue(tempValue * 0.19); }
修改提交逻辑,删除没用的状态标记代码:
onSubmit() { this.invoice = this.invoiceForm.value; console.log(this.invoice.value); this.invoiceService.save(this.invoice).subscribe(result => this.gotoInvoiceList()); }
方案2:提交时手动赋值(快速修复)
如果不想加监听逻辑,也可以在提交阶段直接计算并赋值给对应表单控件后再提交:
onSubmit() { const total = this.calculateTotal(); // 提交前手动更新两个控件的存储值 this.invoiceForm.controls.value.setValue(total * 1.19); this.invoiceForm.controls.vatValue.setValue(total * 0.19); this.invoice = this.invoiceForm.value; console.log(this.invoice.value); this.invoiceService.save(this.invoice).subscribe(result => this.gotoInvoiceList()); }
需要注意保证提交时的计算逻辑和之前模板显示的计算逻辑一致,避免出现显示值和提交值不一致的问题。
内容的提问来源于stack exchange,提问作者Nick Stich
相关产品推荐
相关产品推荐

