【问题标题】:How to add dynamic formArray element values如何添加动态 formArray 元素值
【发布时间】:2020-07-23 02:15:19
【问题描述】:

我想根据来自 API 的响应添加具有值的动态表单数组控件。如果有 1 条记录,则为 1 行,如果有 2 条,则为 2 行,依此类推。

表格

this.VendorForm = this.formBuilder.group({
    vendorId: [null],
    vendorName: ['', [Validators.pattern(/^[A-Za-z\s]{1,}[\.]{0,1}[A-Za-z\s]{0,}$/), Validators.required]],
    vendorType: ['', Validators.required],
    correspondingAddressDetail: this.formBuilder.group({
      correspondingAddress: ['', Validators.required],
      correspondingState: ['', [Validators.required, Validators.pattern(/^[A-Za-z\s]{1,}[\.]{0,1}[A-Za-z\s]{0,}$/)]],
      correspondingPincode: ['', [Validators.required, Validators.pattern(/^\d{3}\d{3}$/)]],
      correspondingCity: ['', Validators.required],
      correspondingDistrict: ['', Validators.required],
      correspondingPostoffice: ['', Validators.required]
    }),
    billingAddressDetail: this.formBuilder.group({
      sameAddress: [false],
      billingAddress: ['', Validators.required],
      billingState: ['', [Validators.required, Validators.pattern(/^[A-Za-z\s]{1,}[\.]{0,1}[A-Za-z\s]{0,}$/)]],
      billingPincode: ['', [Validators.required, Validators.pattern(/^\d{3}\d{3}$/)]],
      billingCity: ['', Validators.required],
      billingDistrict: ['', Validators.required],
      billingPostoffice: ['', Validators.required]
    }),
    phoneNo: ['', [Validators.required, Validators.pattern(/^[1-9]\d{9}$/)]],
    email: ['', Validators.pattern(/^(\D)+(\w)*((\.(\w)+)?)+@(\D)+(\w)*((\.(\D)+(\w)*)+)?(\.)[a-z]{2,}$/)],
    contactPersonNo: ['', [Validators.required, Validators.pattern(/^[1-9]\d{9}$/)]],
    contactPersonName: ['', [Validators.required, Validators.pattern(/^[A-Za-z\s]{1,}[\.]{0,1}[A-Za-z\s]{0,}$/)]],
    contactPersonEmail: ['', Validators.pattern(/^(\D)+(\w)*((\.(\w)+)?)+@(\D)+(\w)*((\.(\D)+(\w)*)+)?(\.)[a-z]{2,}$/)],
    statutoryInfo: this.formBuilder.array([this.formBuilder.group({
      statutoryName: ['', Validators.required],
      info: ['', Validators.required]
    })]),
    isActive: [true],
    remarks: ['']
  });

修补值

this.dialogData.statutoryInfo.forEach(x => {
      this.statutoryInfo.push(this.formBuilder.group({
        statutoryName: [x.statutoryName],
        info: [x.info]
      }))
    });

来自 API 响应的 legalInfo 值:

(2)[{…}, {…}]
0:{statutoryName: 6, info: '123456987'}
info:'123456987'
statutoryName:6
1:{statutoryName: 2, info: 'BnQpgw444'}
info:'BnQpgw444'
statutoryName:2 

第一次点击编辑按钮后:(抛出错误并且行没有被插入)

在第二次点击编辑按钮后:(没有抛出错误并且行被插入)

我不明白为什么在第二次单击后会插入值。我想删除 formArray 控件的空行。

【问题讨论】:

    标签: angular foreach angular-reactive-forms formarray


    【解决方案1】:

    我已经实现了完全相同的逻辑。即。根据来自 API 的数据数量,将表单数组推送到表单组。查看以下必要的示例代码。我希望它能为您提供解决问题的方法。

        createForm() {
            this.editCityForm = this.formBuilder.group({
             state: ['', {
             validators: [Validators.required],
             }],
          
             things: this.formBuilder.array([])
          })
    
         // this add the form Array
         this.addThingToDoForm();
    
         }
    
        addThingToDoForm() {
           for (let i = 0; i < this.city.things.length; i++) {
             // this if condition prevents creating thingstodo form for {} empty objects.
             if (!this.checkIfObjectIsEmpty(this.city.things[i])) {
                this.things = this.editCityForm.get('things') as FormArray;
                this.things.push(this.createThingsToDo());
              }
            }
          }
    
    
        // these are fields inside formGroup of  formArray 
          createThingsToDo() {
            return this.formBuilder.group({
             id: [''],
             name: ['', {
              validators: [Validators.required],
              updateOn: 'blur'
              }],
            })
          }
    
        // it checks if object from API response is not empty so that 
       // we do not push form Array for empty response.
        checkIfObjectIsEmpty(obj) {
           return Object.keys(obj).length == 0;
         }
    
    

    如果你需要 patchValue 到 formArray ,下面的代码给你正确的想法:

         patchThingsToDoForm() {
            const patchData = this.city.things;
            const thingsArray = this.editCityForm.get('things')['controls'];
    
            for (let i = 0; i < patchData.length; i++) {
              if (!this.checkIfObjectIsEmpty(this.city.things[i])) {
                const thingsToDoForm: FormGroup = thingsArray[i];
                thingsToDoForm.patchValue({
                id: patchData[i].id,
                name: patchData[i].name,
               })
               thingsToDoForm.updateValueAndValidity();
             }
           }
    
         }
    
    

    【讨论】:

    • 您和我使用的方法有效。除了对 API 响应进行空检查后,错误会像您一样消失。但是另一个问题没有得到解决,即第一次单击时没有填充数据,但是在第二次单击后它工作正常。感谢您的帮助
    • 据我了解,您所面临的错误已从您保留为屏幕截图的控制台中清楚地显示出来。 this.dialogData.statutoryInfo 值在您第一次单击按钮时未定义。请确保在显示编辑按钮之前获取此值,以便执行此 forEach 循环而不会出错。
    • 这与我解决的 API 调用有关,谢谢
    • 太棒了。如果您认为它是正确的,您可以接受它作为正确答案,那您将非常感激。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 2019-06-24
    • 2014-10-15
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 2012-04-18
    相关资源
    最近更新 更多