如何使用angular8将对象的动态数组分配给formgroup [英] How to assign dynamic array of objects to formgroup using angular8

查看:86
本文介绍了如何使用angular8将对象的动态数组分配给formgroup的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从API命中中获得了对象数组,该对象数组必须分配给formGroup.我尝试使用formGroup绑定,但是它检测到true/false值,但它不会给我在对象数组中更改的true/false值,而是给我仅true/false,并且在另一个数组中我也具有日期输入字段,它不会检测到真/假值或更改的值. 如果我编写的代码有误,请更正我并帮助我高效地编写代码.

帮助表示赞赏.

演示:演示

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>

解决方案

使用表单构建器时,请勿使用[(ngModel)].相反,您应该使用formControlName指令.使用表单构建器数组时,还应该使用formArrayName指令.

此外,您需要传递控件数组以形成构建器,而不是值数组.

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

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

component.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中的表单指令的结构应与表单中formbuilder组,数组和控件的结构相匹配.

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

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

Hi i get array of objects from the API hit, that array of objects must be assigned to formGroup. I have tried using formGroup binding, but it detects true/false values but it doesnt give me changed true/false values in the array of objects instead gives me only true/false and also i have date input field as well in the other array, it wont detect the true/false value or the changed value as well. If the code what i have written is wrong, then please do correct me and help me to write in efficient way.

Help appreciated.

DEMO: 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>

解决方案

You don't use [(ngModel)] when using form builder. Instead you should use the formControlName directive. When you are using form builder arrays, you should also the the formArrayName directive.

Also, you need to pass an array of controls to form builder instead of an array of values.

I will create a simple example based on your code to show you how you apply the technique.

If you set up a form in your component like this:

component.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))
    )
  });
}

You can use the directives in the HTML like this:

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>

Notice how I have wrapped the form controls with the formArrayName directive, and set the formControlName to the array index.

DEMO: https://stackblitz.com/edit/angular-lbo6qn

Multiple form controls in an array

If you want to create multiple controls for each item in a form array, you need to set up your form to reflect that. Create a form control for each property within your form array.

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)
    }))
  )
});

Your HTML structure then matches your form structure:

<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>

You can then access the updated values on submit. Again, your query matches the declared structure.

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

The key here is that the structure of your form directives in your HTML should match the structure of the formbuilder groups, arrays and controls in your form.

Forked demo: https://stackblitz.com/edit/angular-xopwoz

This is just an example of how you apply the concept, rather than a specific fix to your problem. Your problem uses date fields and jQuery. The question of how to create datepicker input fields in Angular is both out of scope and extensively asked on the internet. It shouldn't be too much of a problem for you to apply my techniques to your codebase.

这篇关于如何使用angular8将对象的动态数组分配给formgroup的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆