【问题标题】:Assign dynamic Form control in Form Array : Angular在表单数组中分配动态表单控件:角度
【发布时间】:2021-08-26 01:15:46
【问题描述】:

在我的 Angular 应用程序中尝试在表单数组中添加一个带有两个表单控件的动态表单组,我怎样才能在此处动态添加表单控件?我试图以这种方式添加[formControlName]="i",但得到了Cannot find control with path: 'dinings -> 0 -> 0'

如果我静态添加 formControlName="name"formControlName="cuisine" 未收到错误但添加后表单控件中的值未更新。

这就是我所做的-

HTML

 <div>
     <form [formGroup]="diningForm" (ngSubmit)="addDiningDetails()">
       ....
       <div class="added-dining-list">
         <ul>
           <li formArrayName="dinings" *ngFor="let dining of dinings;let i = index">
            <div [formGroupName]="i">
              <input type="text" class="form-input" placeholder="Dining Name" [formControlName]="i" />
              <input type="text" class="form-input" placeholder="Dining Cuisine" [formControlName]="i" />
              <a href="#">Delete</a>
           </div>
        </li>
        <li>
           <form [formGroup]="diningInfoForm" class="dining-info-form">
              <input type="text" class="form-input" formControlName="diningName"/>
              <input type="text" class="form-input" formControlName="diningCuisine"/>
              <a href="#" (click)="addDining($event)">Add Dining</a>
           </form>
        </li>
      </ul>
    </div>
  </form>

TS

ngOnInit(){
  //Dining Form
    this.diningForm = this._formBuilder.group({
        isOfferingDining: new FormControl('', [Validators.required]),
        dinings: this._formBuilder.array([]),
        diningInfo: new FormControl('')
    });

  //Dining info add form
    this.diningInfoForm = this._formBuilder.group({
        diningName: new FormControl('', [Validators.required]),
        diningCuisine: new FormControl('', [Validators.required])
    });
}

//Adding single dining in form array
addDiningMenu(event: MouseEvent) {
    event.preventDefault();
    if (this.diningInfoForm.invalid) {
        this.showErrorMessages();
    }
    const formValue = this.diningInfoForm.value;
    const formGroup = this._formBuilder.group({
        name: new FormControl(formValue.diningName, [Validators.required]),
        cuisine: new FormControl(formValue.diningCuisine, [Validators.required])
    });
    this.dinings.push(formGroup);
}

//Final Submit of the form
addDiningDetails() {
    this._messageService.clear();
    if (this.diningForm.invalid) {
        this.showErrorMessages();
        return;
    }
    console.log(this.diningForm.value);
}

//Getting form array
get dinings() {
    return (this.diningForm.get('dinings') as FormArray).controls;
}

【问题讨论】:

    标签: angular angular-reactive-forms formarray


    【解决方案1】:

    首先,你能嵌套表单吗?否 请参阅Can you nest html forms?。从表单中删除嵌套表单

    下一步是对您的对象的期望有一张图片,我们将生成一个如下所示的表格

    {
       isOfferingDining: '',
       dinings: [
         {
            diningName: '',
            diningCuisine: ''
          },
          {
            diningName: '',
            diningCuisine: ''
          }
       ]
    }
    

    我假设您有几个dinings,每个餐厅都有一个diningNamediningCuisine。您的表格在澄清这一点方面没有起到太多作用

    更改 getter dinings 以返回 FormArray

      //Getting form array
      get dinings() {
        return (this.diningForm.get('dinings') as FormArray);
      }
    

    现在定义addDinings()deleteDining() 函数

      addDining() {
        this.dinings.push(
          this._formBuilder.group({
            diningName: new FormControl('', [Validators.required]),
            diningCuisine: new FormControl('', [Validators.required])
          })
        );
      }
      deleteDining(i) {
        this.dinings.removeAt(i);
      }
    

    修改您的 html 以匹配表单组

    <form [formGroup]="diningForm" (ngSubmit)="addDiningDetails()">
      Is Offering Dining <input formControlName='isOfferingDining'>
      <div class="added-dining-list">
        <ul formArrayName="dinings">
          <li *ngFor="let dining of dinings.controls;let i = index" [formGroupName]="i">
            <input type="text" class="form-input" placeholder="Dining Name" formControlName="diningName" />
            <input type="text" class="form-input" placeholder="Dining Cuisine" formControlName="diningCuisine" />
            <a (click)="deleteDining(i)" href="#">Delete</a>
          </li>
        </ul>
        <a href="#" (click)="addDining()">Add Dining</a>
      </div>
      <button type="submit">Submit</button>
    </form>
    

    现在一切都应该按预期进行

    See Demo Here

    【讨论】:

      【解决方案2】:

      您需要指定正确的表单控件名称:

              <li formArrayName="dinings" *ngFor="let dining of dinings;let i = index">
                  <div [formGroupName]="i">
                    <input type="text" class="form-input" placeholder="Dining Name" [formControlName]="dining.name" />
                    <input type="text" class="form-input" placeholder="Dining Cuisine" [formControlName]="dining.cuisine" />
                    <a href="#">Delete</a>
                 </div>
      

      【讨论】:

      • 我已经试过这个了 - Cannot find control with path: 'dinings -&gt; 0 -&gt; '
      • 你需要确保你的表单组数组是基于“dinings”初始化的
      【解决方案3】:

      尝试在get dinings() 中删除controls

      //Getting form array
      get dinings() {
          return this.diningForm.get('dinings') as FormArray;
      }
      

      【讨论】:

        【解决方案4】:

        @Rahul 你可以改变你的 dinnings 返回 FormArray 而不是控件。

        在component.ts文件中

        get dinings() {
          return this.diningForm.get('dinings') as FormArray;
        }
        

        在component.html文件中

        <li formArrayName="dinings">
        <div *ngFor="let dining of dinings().controls; let i = index">
          <div [formGroupName]="i">
            <input type="text" class="form-input" placeholder="Dining Name" formControlName="name" />
            <input type="text" class="form-input" placeholder="Dining Cuisine" formControlName="cuisine" />
            <a href="#">Delete</a>
          </div>
        </div>
        </li>
        

        参考:FormArray Reference Link

        【讨论】:

        • 使用这种方法的控件,正在添加,每当我更改控件中的任何值时,总是得到旧的和默认值(创建控件时的初始值)
        • 请查看stackblitz.com/edit/angular-ivy-4gcwgl。如果可能,请通过上述答案随附的参考链接。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多