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

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

问题描述

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

感谢帮助.

演示:演示

TS:

 私有设置InfoForm() {如果(!this.agentDetailsList){//添加this.agentSettingsInfoForm = this.FB.group({agentToogles: this.FB.array(this.detailsToggle.map(x=> x.boolValue)),限制信息:this.FB.array(this.Restrictions.map(x=>x.boolValue))});} 别的 {//编辑如果(this.agentDetailsList){this.detailsToggle = this.agentDetailsListthis.agentSettingsInfoForm = this.FB.group({agentToogles: this.FB.array(this.detailsToggle.map(x=>x.boolValue)),限制信息:this.FB.array(this.Restrictions.map(x=>x.boolValue))})}this.agentSettingsInfoForm.valueChanges.subscribe(data => {this.formEdit = true;console.log('agentSettingsInfoForm', this.formEdit)})}}

HTML:

<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 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 class="form-group"><input type="text" class="form-control constraintDate" id="{{restrictValue.id}}" placeholder="MM/DD/YYYY HH:MM AM/PM"[禁用]="!restrictValue.boolValue" [(ngModel)]="restrictValue.datetime" (click)="dateRestriction($event, i)"[ngModelOptions]="{standalone: true}" >

</表单>

解决方案

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

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

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

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

component.ts

ngOnInit() {this.values = ['', '', ''];this.form = this.formBuilder.group({值: this.formBuilder.array(//这是一个控件数组 - 不是值this.values.map(x => this.formBuilder.control(x)))});}

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

component.html

<fieldset [formGroup]="form"><div formArrayName="values"><div *ngFor="let value of values;let i = index"><input [formControlName]="i"/>

<按钮>提交</fieldset></表单>

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

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

数组中的多个表单控件

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

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

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

<div formArrayName="数组"><div *ngFor="let value of values;let i = index"><div [formGroupName]="i"><input type="checkbox" formControlName="boolValue"/><input type="text" formControlName="label"/>

<按钮>保存</按钮></表单>

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

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 中创建日期选择器输入字段的问题超出了范围,并且在互联网上被广泛询问.将我的技术应用于您的代码库对您来说应该没有太大问题.

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天全站免登陆