【问题标题】:How to add array of objects to angular form如何将对象数组添加到角度形式
【发布时间】:2021-07-16 18:11:17
【问题描述】:

假设我有一个包含这些值的 json:

{
car: bmw,
tunes : [{
 name: turbo,
 cost: 350
},
{
 name: exhaust,
 cost: 100
}]
}

如何创建能够采用这些值的表单? 我认为 FormGroup 不起作用。 FormArray 似乎是正确的使用方法,但我还没有看到它与可以分配值的预选字段一起使用,这正是我所需要的。我需要能够将对象数组分配给from,编辑对象的某些值并将表单导出为带有对象数组的json(与数组相同,但可能具有不同的值)。字段不会改变,所以我不需要动态添加它们,我只需要分配它们。

我想象的解决方案如下所示:

form: New FormGroup({
 car: new FormControl(),
 tunes: new FormArray([
  name: new FormControl(),
  cost: new FormControl()
 ])
})

更新:

这似乎是想要的解决方案:

form: New FormGroup({
     car: new FormControl(),
     tunes: new FormArray([
      new FormGroup({
       name: new FormControl(),
       cost: new FormControl()
      })
     ])
    })

但它给了我错误:“在索引 1 处找不到表单控件”

当我查看它生成的 json 时,这是想要的结果,但我现在无法分配值。

【问题讨论】:

  • @R.Richards 这很有趣,因为这给了我一个错误。我会再试一次
  • 嗯,是的,但是有没有办法让这些表单控件拥有一个键?这是我的主要问题。我需要它是一个对象数组。

标签: angular typescript forms


【解决方案1】:

我想这就是你要找的东西:

import { Component, OnInit } from '@angular/core';
import {
  FormArray,
  FormBuilder,
  FormGroup,
  ValidatorFn,
  Validators
} from '@angular/forms';

export interface ITune {
  name: string;
  cost: string;
}

export interface Icar {
  car: string;
  tunes: ITune[];
}

@Component({
  selector: 'list-overview-example',
  templateUrl: 'list-overview-example.html'
})

export class ListOverviewExample implements OnInit {

  form: FormGroup;
  public validator: { [key: string]: ValidatorFn | null };
  public data: Icar;

  constructor(private fb: FormBuilder) {
    this.validator = {
      name: Validators.compose([Validators.required, Validators.maxLength(50)])
    };
    this.data = {
      car: 'bmw',
      tunes: [
        { name: 'turbo', cost: '100$' },
        { name: 'exhaust', cost: '200$' }
      ]
    };
  }

  public ngOnInit() {
    this.form = this.createFormGroup(this.fb, this.data, {});
    this.form.addControl(
      'tunes',
      new FormArray(this.addTunes(this.data.tunes))
    );
  }

  public addTunes(tunes: ITune[]): FormGroup[] {
    const formGroups: FormGroup[] = [];
    tunes.forEach(x => {
      const formGroup = this.createFormGroup(this.fb, x, this.validator);
      formGroups.push(formGroup);
    });
    return formGroups;
  }

  createFormGroup<T extends { [key: string]: any }>(
    formBuilder: FormBuilder,
    dataSource: T,
    validators: { [key: string]: ValidatorFn | null }
  ): FormGroup {
    // dynamic creation of form control by enumerating the object
    const config: any = {};
    Object.keys(dataSource).forEach((propertyName: string) => {
      const fieldVlidators = validators[propertyName];
      const value = dataSource[propertyName];
      if (!(value instanceof Array)) {
        if (fieldVlidators !== undefined) {
          config[propertyName] = [value, fieldVlidators];
        } else if (fieldVlidators !== undefined) {
          config[propertyName] = [value, fieldVlidators];
        } else {
          config[propertyName] = [value];
        }
      }
    });
    const group = formBuilder.group(config);
    return group;
  }
}

您可以使用 .addControl() 方法在 formGroup 上添加控件。 createFormGroup() 是一种通用方法,可用于创建表单组。如果您需要验证任何控件,您也可以传递验证器。您只需要在 createFormGroup() 函数中传递带有名称和验证器规则的对象。

【讨论】:

  • 如果它对您有用,请您接受答案
  • 我还没有测试过,但从我的第一印象看来,您正在尝试动态创建它,而且看起来非常复杂,这不是我想要实现的。我正在寻找一个简单的解决方案来分配对象数组,并能够将表单导出为带有对象数组的 json,同时还能够编辑数组中的特定字段和特定对象。
猜你喜欢
  • 2019-01-29
  • 1970-01-01
  • 1970-01-01
  • 2021-06-02
  • 2018-05-01
  • 2019-07-11
  • 1970-01-01
相关资源
最近更新 更多