【问题标题】:How to bind form input value in reactive form如何以反应形式绑定表单输入值
【发布时间】:2019-11-29 13:48:09
【问题描述】:

我希望total 框的值等于pricequantity 的乘积。如果没有反应形式,在盒子语法中使用香蕉非常容易。我如何在反应形式中达到同样的效果

这是我的表单代码

addProductFormGroup(): FormGroup {
    return this._formBuilder.group({
      productId: ['', Validators.required],
      price: ['', Validators.required],
      loanTermId: ['', Validators.required],
      quantity: ['', Validators.required],
      deposit: ['', Validators.required],
      total: ['', Validators.required],
    });
  }

这是total输入的html

<mat-form-field appearance="outline" fxFlex="100" class="pr-4">

    <mat-label>Total </mat-label>
        <input type='number' value='deposit*quantity' formControlName="total" [id]="'total' + i" matInput name="" id="" placeholder="Total" required>

</mat-form-field>

我的表单的图像

【问题讨论】:

  • Total 字段真的应该是表单中的一个字段,而不仅仅是存款*数量的文本输出吗? (我猜你应该不能改变它?) -> 你可以在你的组件 getTotal(FormGroup) => total 中为这个值创建一个 getter

标签: angular angular-reactive-forms


【解决方案1】:
value='33' // dont do that


addProductFormGroup(): FormGroup {
    return this._formBuilder.group({
      productId: ['', Validators.required],
      price: ['', Validators.required],
      loanTermId: ['', Validators.required],
      quantity: ['', Validators.required],
      deposit: ['', Validators.required],
      total: ['33', Validators.required], // do that!
    });
  }

已编辑:

根据您的回复,我会说从 formGroup 中删除 total,因为它实际上不是用户输入。而是做一些类似这样的事情:

total$: Observable<number>;

this.total$ = this.productFormGroup.valueChanges.pipe(
  map(formValue => +formValue.quantity * +formValue.price)
)

<div>Total: {{ total$ | async }}</div>

【讨论】:

  • 我已经编辑了问题,请现在检查我希望总数是pricequantity 的乘积
  • 我认为这不适用于我的情况,因为当我添加新行时(请参阅附图以获得更好的想法),所有行的总数将相同。如何处理这种情况。请提前致谢
  • @MoxxiManagarm,这是行不通的。如果您使用|async,您只能在第一次获得值 -async unsubcribe observable-
  • @Eliseo 这不是真的。异步管道还会刷新该值。这不是一次
  • 你说得对,对不起我的困惑
【解决方案2】:

让我知道这是否可行 (Link to StackBlitz)

ngOnInit(){

this.formGroup =  this.fb.group({
  quantity : [0 ,[]],
  value:[0,[]],
  total:[0]
})

this.formGroup.valueChanges.pipe(
  debounceTime(500),
  distinctUntilChanged(this.isSame)
).subscribe(values =>{
  console.log(values)
  const {value, quantity} = values;
  this.formGroup.patchValue(
    {
      total : value * quantity
    }
  )
})}

isSame(prev, next) {
  return (prev.value === next.value)
 && (prev.quantity === next.quantity);
}

https://stackblitz.com/edit/angular-8t3qpo?embed=1&file=src/app/app.component.ts

【讨论】:

  • 看起来不错,我刚刚看到 stackBlitz 示例,但在我的示例中不起作用
  • 因为我有动态的行数,(请看图片以获得更好的主意)即当用户添加新行时,所有行的总数不会相同吗?
【解决方案3】:

我认为你只需要做类似的事情

public get total(): any {
   if (this.form.get('price').value && this.form.get('quantity').value) {
       return this.form.get('price').value * this.form.get('quantity').value;
   }
   return '';
}

注意:您需要创建表单并需要在其中存储formGroup返回值

【讨论】:

    【解决方案4】:

    您可以订阅类似于以下的值更改:

        // build formgroup then ...
    
        // calculate total
        this.formGroup.valueChanges
          .pipe(debounceTime(20), takeUntil(this.destroyed$))
          .subscribe(value => {
            this.calculateLineItemTotal();
          });
    
      private calculateLineItemTotal(): number {
        // get quantity and rate values
        const quantity = +this.formGroup.controls.LineQuantity.value;
        const rate = +this.formGroup.controls.LineRate.value;
    
        // verify if blank
        if (!quantity || !rate) {
          this.formGroup.controls.LineTotal.setValue("", {
            emitEvent: false
          });
          return 0;
        }
    
        this.formGroup.controls.LineTotal.setValue((quantity * rate).toFixed(2), {
          emitEvent: false
        });
        return quantity * rate;
      }
    

    警告 - 这会很快变得丑陋(想想在编辑模式下修补值)所以最好尽可能避免,因为在 cmets 中提到了 Jenson。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-08
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多