【问题标题】:how to watch for valueChanges on a control within a formGroup under a dynamic formArray如何在动态 formArray 下的 formGroup 内的控件上监视 valueChanges
【发布时间】:2021-05-30 15:37:39
【问题描述】:

我是 Angular 2/4 以及一般 Web 开发的新手。我有这个表格,它在购买表格中收集产品变体的信息。 我已经构建了一个 formArray 的 formGroups 变体,如下面的 HTML 所示。

<form [formGroup]="this.purchaseInvoiceItemVariantsForm" novalidate>
    <div formArrayName="variants">
        <div *ngFor="let variant of this.purchaseInvoiceItemVariantsForm.controls.variants.controls; let i = index">
            <div [formGroupName]="i">
                <md-input-container>
                    <input mdInput placeholder="Product Code"  formControlName="productBarcode" class="input--small" [readonly]="this.mode == 'view'">
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Color" formControlName="variant1" class="input--small" [readonly]="this.mode == 'view'" required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Size" formControlName="variant2" class="input--small" [readonly]="this.mode == 'view'" required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="MRP" formControlName="mrp" class="input--small" [readonly]="this.mode == 'view'">
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Purchase Price" formControlName="purchasePrice" class="input--small" [readonly]="this.mode == 'view'"
                        required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Sell Price" formControlName="sellPrice" class="input--small" [readonly]="this.mode == 'view'"
                        required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Quantity" formControlName="variantQuantity" class="input--small" [readonly]="this.mode == 'view'" required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Discount" formControlName="variantDiscount" class="input--small" [readonly]="this.mode == 'view'">
                </md-input-container>
                <button md-icon-button (click)="removeVariant(i)" color="warn" *ngIf="purchaseInvoiceItemVariantsForm.controls.variants.length > 1 && this.mode != 'view'"><md-icon>delete</md-icon></button>
            </div>
        </div>

现在,一旦用户添加了 3 个变体,我希望能够监听 formControl“productBarcode”的 valueChanges,以便我可以从数据库中获取颜色和尺寸详细信息。

有什么建议可以实现吗?

提前致谢!

问候, 纳文

【问题讨论】:

    标签: angular angular-reactive-forms


    【解决方案1】:

    我们可以做一个valueChanges 的版本,当variants-array 长度为&gt;= 3 时开始监听。然后我们监听条形码的每一个变化。

    我假设你有一个函数可以向 variants 数组添加新控件,我们可以在那里实现它:

    addVariant() {
      // code here for adding control
    
      // check length   
      if(this.purchaseInvoiceItemVariantsForm.get('variants').length >= 3) {
        // iterate each object in array
        for(let val of this.purchaseInvoiceItemVariantsForm.get('variants').controls) {
          // listen to changes in each barcode, if change, do something!
          val.get('productBarcode').valueChanges.subscribe(data => {
          console.log(val.get('productBarcode').value)
          // do something!
          })
        }
      } 
    }
    

    Demo

    【讨论】:

    • 更新了答案,我错过了只听条形码,现在已经修复了:)
    【解决方案2】:

    我会选择ngDoCheck()。它不断地监听变化,然后你可以添加一些逻辑。对我帮助很大。

    一个例子:

    ngDoCheck() {
        if (this.arraOfItems.length > 3) {
            // Do stuff
        }
    }
    

    在你的课堂上你应该实现DoCheck,像这样:

    export class myClass implements OnInit, DoCheck {}
    

    这样,如果您设法将项目添加到数组中,请说:arraOfItems。然后就可以了。

    文档:https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#docheck

    另一种方法:

    在您向arraOfItems 添加项目的逻辑中,进行检查 并添加您的逻辑,例如:

    addingItemToArray(item) {
        this.arraOfItems.push(item);
        if (this.arraOfItems.length > 3) {
           // do stuff 
        }
    }
    

    此示例认为您创建了一个将项目添加到数组的addingItemToArray 方法。在其逻辑中,您可以放置​​一个控件,检查数组的长度,如果您添加了 3 个以上的项目,则执行您想要执行的任何操作。

    【讨论】:

    • 感谢@SrAxi 的回复。我尝试了您的建议,但没有像我预期的那样产生输出。我想做的是听表单组上一个字段的值变化。现在要这样做,我必须指定一个特定的 formGroupName,它又是 FormArray 中的动态索引号。我仍然会玩 DoCheck 生命周期钩子,看看是否有出路......
    • @NavinHotwani 很抱歉它没有给你预期的输出。我希望至少DoCheck 可能对您的项目和编码有用。干杯! ;)
    【解决方案3】:

    在将控件动态添加到FormGroup 后,对每个控件使用valueChanges

    const ct = {key: 'myControl'};    
    this.myForm.addControl(ct.key, new FormControl('', Validators.required))
    this.myForm.controls[ct.key].valueChanges
    .subscribe(d => {
        // here ct will be available as closure , so that we can access every form control here and do operation accordingly
        console.log(d, ct.key);
    })
    

    这里ct 对象将作为闭包在订阅中可用。

    【讨论】:

      猜你喜欢
      • 2021-04-27
      • 2021-11-13
      • 1970-01-01
      • 2020-02-20
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 2019-05-02
      • 2018-09-11
      相关资源
      最近更新 更多