【问题标题】:Can't access inputfield values set by interpolation {{}}无法访问插值 {{}} 设置的输入字段值
【发布时间】:2020-01-19 19:33:12
【问题描述】:

我正在开发一个非常简单的应用程序,它包含一个带有 formArray 的表单。 在 formArray 中可以选择产品名称和数量。当两者都被选中时,第三个输入字段 - total - 使用

计算物品的总价格(产品价格 * 数量)
<input matInput placeholder="total"
  type="number"
  formControlName="total"
  value="{{getProductPrice(purchaseForm.value.product[i].productId) * purchaseForm.value.product[i].amount}}">

我想对 formArray 中所有项目的 total 输入字段(价格)求和。该值显示为 OK,如果我更改任何产品和/或金额,它会自动更改。

我的问题是,当我尝试访问 total 输入字段的值时,我得到 0。如果我手动更改值(粘贴、键入等),我可以正确访问它离开。

我可以访问其他字段(fex。我可以计算所有产品的总和)

是不是我设置字段值的方式导致的问题?

有人知道这是为什么吗?

【问题讨论】:

    标签: angular forms string-interpolation


    【解决方案1】:
    //create an array of totals
    totals:number[]=[];
    total:number; //<--use a variable to store the total
    
    //After create the form Array
    this.yourFormArray.valueChanges(res=>{
       let total=0;
       res.forEach((x:any,index:number)=>{
         //use the "+" to convert to number res.amount;
         totals[index]=(+x.amount)*(this.getProductPrice(x.productId));
         total+=totals[index]
       })
       this.total=total;
    }
    

    【讨论】:

      【解决方案2】:

      当您使用value 时,您将绑定到一个名为valueHTML 属性,该属性将更新DOM,但永远不会更新表单的值。要更新您的表单值,您可以将ngModel 与这样的反应式表单结合使用,但我不建议这样做:

      <input matInput placeholder="total"
        type="number"
        formControlName="total"
        [ngModel]="getProductPrice(purchaseForm.value.product[i].productId) * purchaseForm.value.product[i].amount">
      

      您不应该从不在这样的视图中设置值。但是,该代码将起作用。一个更正确的做事方式可能是观察表单中的值变化并根据新值设置总计。类似这样的东西:

      ngOnInit() {
        // Watch our form and set value of total based on qty and price.
        // NOTE: In real life be sure to unsubscribe from this subscription when component is destroyed.
        // You ALSO probably only want to respond to certain value changes here.
        this.form.valueChanges.subscribe(formValues => {
          if (someValueIndicatingWeNeedToUpdateTotal === true) {
            this.form.get('total').setValue(1 * 2); // Obviously replace this with real logic
          }
        })
      }
      

      不管怎样,我已经创建了一个working example you can play around with on StackBlitz

      【讨论】:

      • Dean,不要将 [(ngModel)] 和 formControlName 用于一个输入,并且不要将 [(ngModel)] 与函数一起使用(允许使用 [ngModel],但不能使用“bannana sintax”。是的,正确的方法是订阅值更改以获取总计和小计,但我可以理解总计属于 FormArray,当然,总计必须是文字,而不是输入
      • @Eliseo 是的,我不建议将ngModel 与反应形式一起使用。并且在您的字段中设置属性值也不好。很好地抓住了双向绑定与单向绑定。我将答案更新为只有单向绑定。
      • 顺便说一句 - 这里的另一种可能的选择是让 total 根本不存在于表单中(因为它是一个计算字段,因此作为表单字段并没有真正意义)。跨度>
      • 我说不放(不是不推荐,见angular.io/api/forms/FormControlName#use-with-ngmodel)。在 &lt;form [formGroup]="form"&gt; 中使用带有 [(ngModel)] 的输入应该仅用于管理不属于表单的变量(在这种情况下,我们需要放置 [ngModelOptions]="{standalone:true}"
      猜你喜欢
      • 2011-11-28
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      • 2013-08-25
      • 2013-04-12
      • 1970-01-01
      相关资源
      最近更新 更多