[Angular]——创建表单之FormArray、FormGroup

本文介绍了在Angular中如何使用FormArray和FormGroup创建动态表单,特别是处理对象和数组数据类型的情况。通过实例展示了在创建个人信息表单时,如何提交姓名、年龄、家庭成员信息(数组)及家庭住址(对象)。文章提醒在动态添加和删除表单控件时需要注意唯一标识和索引问题,以避免数据错乱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简述

表单的三大基本构造块:FormGroup 、 FormControl、FormArray 。

FormGroup 把每个子 FormControl 的值聚合进一个对象,它的 key 是每个控件的名字。 它通过归集其子控件的状态值来计算出自己的状态。 比如,如果组中的任何一个控件是无效的,那么整个组就是无效的。

FormArray 聚合了数组中每个表单控件的值。 它还会根据其所有子控件的状态总结出自己的状态。比如,如果 FromArray 中的任何一个控件是无效的,那么整个数组也会变成无效的。

简要概述就是在创建表单时,有些数据格式并不是单单的字符串和数值类型的,可能是对象或者是数组,这时候就能用上表单的FormArray和FormGroup,以达到快速获取表单值并提交对应的数据类型。


一、场景

假如我们需要提交个人信息,信息需要提交你和家人的姓名和年龄,以及家庭住址。
表单页

想到类似的表单页,就简要的写了一个,其中个人信息的姓名和年龄按照正常的字符串提交,家庭信息以数组方式提交,家庭地址按照对象提交。


实现

form.component.html

<!--ant卡片组件-->
<nz-card>
  <form nz-form [formGroup]="formData">
  <!--个人信息-->
    <nz-divider nzText="个人信息" nzOrientation="left"></nz-divider>
    <div nz-row>
      <div nz-col nzSpan="8" nzOffset="2">
        <nz-form-item>
          <nz-form-label nzSpan="6" nzOffset="1">姓名 </nz-form-label>
          <nz-form-control>
            <input nz-input placeholder="请输入名称" formControlName="name" />
          </nz-form-control>
        </nz-form-item>
      </div>
      <div nz-col nzSpan="8" nzOffset="2">
        <nz-form-item>
          <nz-form-label nzSpan="6" nzOffset="1">年龄 </nz-form-label>
          <nz-form-control>
            <nz-input-number [nzMin]="0" [nzStep]="1" formControlName="age"></nz-input-number>
          </nz-form-control>
        </nz-form-item>
      </div>
    </div>
	<!--家庭信息-->
    <nz-divider nzText="家庭信息" nzOrientation="left"></nz-divider>
    <div nz-row *ngFor="let info of family; let i = index" formArrayName='family'>
      <div nz-col nzSpan="8" nzOffset="2">
        <nz-form-item>
          <nz-form-label nzSpan="6" nzOffset="1">{{info.code}} </nz-form-label>
          <nz-form-control [formGroupName]="i">
            <input nz-input placeholder="请输入姓名" formControlName="name" />
          </nz-form-control>
        </nz-form-item>
      </div>
      <div nz-col nzSpan="8" nzOffset="2">
        <nz-form-item>
          <nz-form-label nzSpan="6" nzOffset="1">年龄 </nz-form-label>
          <nz-form-control [formGroupName]="i">
            <nz-input-number [nzMin]="0" [nzStep]="1" formControlName="age"></nz-input-number>

          </nz-form-control>
        </nz-form-item>
      </div>
    </div>
	<!--家庭地址-->
    <nz-divider nzText="家庭地址" nzOrientation="left"></nz-divider>
    <div nz-row>
      <div nz-col nzSpan="24" formGroupName='address'>
        <nz-form-item>
          <nz-form-label nzSpan="4" nzOffset="0">地址</nz-form-label>
          <nz-form-control nzSpan="4">
            <input nz-input placeholder="请输入国家" formControlName="county" />
          </nz-form-control>
          <nz-form-control nzSpan="4" nzOffset="1">
            <input nz-input placeholder="请输入省份" formControlName="province" />
          </nz-form-control>
          <nz-form-control nzSpan="4" nzOffset="1">
            <input nz-input placeholder="请输入市县" formControlName="city" />
          </nz-form-control>
        </nz-form-item>
      </div>
    </div>
  </form>
</nz-card>
<br />
<!--显示数据-->
{{formData.value | json}}


form.component.ts

	
  constructor(private fb: FormBuilder) {} // 注入formBuilder,快速创建表单

  formData: FormGroup; // 表单数据
  // 模拟简单的家庭信息模板,真实的家庭信息数据量很大
  family = [
    { id: 1, code: '父亲', name: 'father', age: 0 },
    { id: 2, code: '母亲', name: 'mother', age: 0 },
  ];

  ngOnInit(): void {
    // 初始化表单
    this.formData = this.fb.group({
      name: [''],
      age: [''],
      family: this.fb.array([]),
      address: this.fb.group({}),
    });
    // 获取表单组的address参数作为FormGroup,以便于调用FormGroup的添加formControl的方法
    const address = this.formData.controls.address as FormGroup;
    address.addControl('county', new FormControl(null));
    address.addControl('province', new FormControl(null));
    address.addControl('city', new FormControl(null));
    // 获取表单组的family参数作为formarray,以便于调用FormArray的方法
    const familyArray = this.formData.controls.family as FormArray;
    // 循环创建formcontrol,用新的formgroup添加control,再调用formarray的push方法(在数组末尾添加)
    this.family.forEach(() => {
      const familyGroup = new FormGroup({});
      familyGroup.addControl('name', new FormControl(null));
      familyGroup.addControl('age', new FormControl(null));
      familyArray.push(familyGroup);
    });
    
  }


效果

  • 输入数据后:
    在这里插入图片描述
  • 表单数据结构:
    在这里插入图片描述

总结

更多的是动态创建表单,这时候在添加form control时要注意,往往需要一个唯一标识。如果formArrayName根据索引,并且对象内的属性命名跟索引有关联,那在删除的时候就要注意,再删了第一条数据之后,后边的索引都前移了一位,以至于找不到对应的formControl。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值