【问题标题】:How to assign dynamic array of objects to formgroup using angular8如何使用angular8将动态对象数组分配给formgroup
【发布时间】:2020-06-07 03:57:39
【问题描述】:

您好,我从 API 命中获取对象数组,该对象数组必须分配给 formGroup。我尝试使用 formGroup 绑定,但它检测到真/假值,但它没有给我更改对象数组中的真/假值,而是只给我真/假,而且我在另一个数组中也有日期输入字段,它也不会检测真/假值或更改的值。 如果我写的代码有问题,请纠正我并帮助我以有效的方式编写。

帮助表示赞赏。

演示:DEMO

TS:

 private settingsInfoForm() {
    if (!this.agentDetailsList) {
      // Add
      this.agentSettingsInfoForm = this.FB.group({
        agentToogles: this.FB.array(this.detailsToggle.map(x=> x.boolValue)),
        restrictionsInfo:this.FB.array(this.Restrictions.map(x=>x.boolValue))
      });
    } else {
      // Edit
      if (this.agentDetailsList) {
       this.detailsToggle = this.agentDetailsList
       this.agentSettingsInfoForm = this.FB.group({
          agentToogles: this.FB.array(this.detailsToggle.map(x=>x.boolValue)),
           restrictionsInfo:this.FB.array(this.Restrictions.map(x=>x.boolValue))
      })
      }
      this.agentSettingsInfoForm.valueChanges.subscribe(data => {
          this.formEdit = true;
          console.log('agentSettingsInfoForm', this.formEdit)
        })
      }
    }

HTML:

<form [formGroup]= "agentSettingsInfoForm">
<div class="row row-cols-2" formGroupName="agentToogles">
              <div class="col" *ngFor="let toggleValue of detailsToggle;let i = index">
                <div class="custom-control custom-switch mb-3">
                    <input type="checkbox" [formControlName]="i" id="{{toggleValue.id}}" > 
                  <label class="custom-control-label" for="{{toggleValue.id}}">{{toggleValue.label}}</label>
                </div>
              </div>
            </div>


          <div class="col-6 {{isReadOnly ? 'link-disabled' : ''}}"
            *ngFor="let restrictValue of Restrictions;let i = index" formGroupName="restrictionsInfo">
            <div class="custom-control custom-switch">
              <input type="checkbox" class="custom-control-input" id="{{restrictValue.id}}"
              [(ngModel)]="restrictValue.boolValue" [ngModelOptions]="{standalone: true}"
                >
              <label class="custom-control-label" for="{{restrictValue.id}}">{{restrictValue.label}}</label>
            </div>
            <div class="form-group">
              <input type="text" class="form-control restrictionDate" id="{{restrictValue.id}}" placeholder="MM/DD/YYYY HH:MM AM/PM"
                [disabled]="!restrictValue.boolValue" [(ngModel)]="restrictValue.datetime" (click)="dateRestriction($event, i)" 
                [ngModelOptions]="{standalone: true}" >
            </div>
          </div>

</form>

【问题讨论】:

    标签: angular angular-reactive-forms formarray


    【解决方案1】:

    使用表单生成器时不要使用[(ngModel)]。相反,您应该使用 formControlName 指令。当您使用表单构建器数组时,您还应该使用 formArrayName 指令。

    此外,您需要将控件数组而不是值数组传递给表单构建器。

    我将根据您的代码创建一个简单的示例,向您展示如何应用该技术。

    如果您在组件中这样设置表单:

    组件.ts

    ngOnInit() {
      this.values = ['', '', ''];
    
      this.form = this.formBuilder.group({
        values: this.formBuilder.array(
          // this is an array of controls - NOT values
          this.values.map(x => this.formBuilder.control(x))
        )
      });
    }
    

    您可以像这样在 HTML 中使用指令:

    component.html

    <form (submit)="onSubmit()">
      <fieldset [formGroup]="form">
        <div formArrayName="values">
          <div *ngFor="let value of values;let i = index">
            <input [formControlName]="i" />
          </div>
        </div>
        <button>Submit</button>
      </fieldset>
    </form>
    

    注意我是如何用formArrayName 指令包装表单控件的,并将formControlName 设置为数组索引。

    演示:https://stackblitz.com/edit/angular-lbo6qn

    数组中的多个表单控件

    如果要为表单数组中的每个项目创建多个控件,则需要设置表单以反映这一点。为表单数组中的每个属性创建一个表单控件。

    this.form = this.FB.group({
      array: this.FB.array(
        this.values.map(x => this.FB.group({
          boolValue: this.FB.control(x.boolValue),
          label: this.FB.control(x.label)
        }))
      )
    });
    

    然后您的 HTML 结构与您的表单结构相匹配:

    <form [formGroup]="form" (submit)="onSubmit()">
      <div formArrayName="array">
        <div *ngFor="let value of values;let i = index">
          <div [formGroupName]="i">        
            <input type="checkbox" formControlName="boolValue" /> 
            <input type="text" formControlName="label" />
          </div>
        </div>
      </div>      
       <button>Save</button>
    </form>
    

    然后您可以在提交时访问更新的值。同样,您的查询与声明的结构相匹配。

    onSubmit() {
      this.form.get('array').value.forEach((formGroup: FormGroup, i: number) => {
        this.values[i].boolValue = formGroup['boolValue'];
        this.values[i].label = formGroup['label'];
      });
    }
    

    这里的关键是 HTML 中表单指令的结构应该与表单中的表单构建器组、数组和控件的结构相匹配。

    分叉演示:https://stackblitz.com/edit/angular-xopwoz

    这只是您如何应用该概念的一个示例,而不是针对您的问题的特定解决方案。您的问题使用日期字段和 jQuery。如何在 Angular 中创建日期选择器输入字段的问题超出了范围,并且在互联网上被广泛询问。将我的技术应用于您的代码库对您来说应该不是什么大问题。

    【讨论】:

    • 感谢您根据您的输入做出响应,我能够继续到这里,但即使现在我点击保存而不是对象数组来更改值时,我也只能得到真/假值,并且对于其他部分,我无法绑定 dateValues,该怎么做? stackblitz.com/edit/…
    • 很难说你的 stackblitz 的具体问题是什么。你能用尽可能少的代码重新创建吗?比如我的 stackblitz 示例
    • 你还没有设置 formArrayName
    • 是的,我现在只给你一个表格然后我要另一个表格,给我几分钟我会重新创建并在这里发布
    猜你喜欢
    • 2012-08-15
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    相关资源
    最近更新 更多