Angular 表单嵌套、动态表单

说明: 组件使用了ng-zorro (https://ng.ant.design/docs/introduce/zh)

第一类:嵌套表单


1. 静态表单嵌套

demo.component.html


<form [formGroup]="formGroup">
    <div>
        <label>名称: </label>
        <input type="text" formControlName="title" ([ngModel])="formData.title" />
        <nz-form-explain *ngIf="formGroup.get('title').dirty && formGroup.get('title').errors">请填写名称!</nz-form-explain>
    </div>
    <!--嵌套表单(user)-->
    <div formGroupName="user">
       <div>
            <label>用户名: </label>
            <input type="text" formControlName="config.userName" [(ngModel)]="formData.config.userName" />
            <nz-form-explain *ngIf="formGroup.get('user.userName').dirty && formGroup.get('user.userName').errors">请填写姓名!</nz-form-explain>
       </div>

        <div>
            <label>密码: </label>
            <input type="text" formControlName="config.userPwd" [(ngModel)]="formData.config.userPwd" />
            <nz-form-explain *ngIf="formGroup.get('user.userPwd').dirty && formGroup.get('user.userPwd').errors">请填写密码!</nz-form-explain>
        </div>

    </div>
</form>

demo.component.ts


export class DemoComponent  implements OnInit {

    // 定义变量
    private formGroup: FormGroup;
    private fromData: {title = ''; user: {userName = ''; userPwd = ''}};

    construct(private _fb: FormBuilder) {}

   ngOnInit() {    // 自定义验证规则
        this.formGroup = this._fb.group({
            title: [null, [null, Validators.required]],
            user: this._fb.group({ // 嵌套表单验证规则
                userName:[null, Validators.required],
                userPwd:[null, Validators.required],
           });
    });
  }

    // 验证表单
    validateForm() {
        for (const i in this.formGroup.controls) {
          form.controls[ i ].markAsDirty();
          form.controls[ i ].updateValueAndValidity();
        }
        // 验证是否通过
        if (form.valid) { // 验证通过
           //////////
        }
    }

    // 获取数据
    getData() {
        const data = this.formData;
        console.log(data);
    }
}

2. 动态表单嵌套 (数组式添加)

1. demo.component.html


<form [formGroup]="formGroup">
    <!--嵌套表单(sqxx)-->
    <div formGroupName="sqxx">
        <!--动态添加表单按钮-->
        <button style="60%" (click)="addData($event)">添加申请信息</button>
        <!--添加的课程量列表-->
        <nz-table
              *ngIf="applyInfoArray.length > 0"
              #sqxxTableData
              nzSize="middle"
              [nzData]="applyInfoArray"
              [nzShowPagination]="false"
              [nzSize]="'small'"
              class="kclsq-sqxx-table"
            >
            <thead>
                <tr>
                  <th>类型</th>
                  <th>数量</th>
                  <th>操作</th>
                </tr>
            </thead>
            <tbody>
              <!--动态添加项-->  
              <ng-container *ngFor="let item of infoArray; index as i;">
                <tr>
                  <td><input nz-input placeholder="类型" [formControlName]="item.type" style=" 120px;"></td>
                  <td><input nz-input placeholder="工作量" [formControlName]="item.num" style=" 120px;"></td>
                  <td><a href="javascript:;" (click)="delInfo(item.type, sqxxItem.num)"><i nz-icon type="delete" theme="outline"></i></a> </td>
                </tr>
                <!--动态添加项验证未通过时显示项-->
                <nz-form-explain *ngIf="(formGroup.value['sqxx'][item.type] === '' && isSqxxValid) || (formGroup.value['sqxx'][item.num] === ''&& isSqxxValid)">类型、数量均不能为空!</nz-form-explain>
              </ng-container>
            </tbody>
        </nz-table>
    </div>
</form>

2. demo.component.ts


export class DemoComponent  implements OnInit {

    formGroup: FormGroup;
    // 动态表单变量
     isSqxxValid = false;
     infoArray: any[] = [];

    construct(private _fb: FormBuilder) {}

    ngOnInit() {

    // 自定义验证规则
    this.formGroup = this._fb.group({
       sqxx: this._fb.group({});
    });

    // 默认添加一项
     this.addData();
   }

    // 点击添加表单项按钮
    addData() {
       // 获取唯一值
       const uid1 = this.getUID();
       const uid2 = this.getUID();
       // 申请信息数组添加数据
       this.infoArray.push({type: uid1,num: uid2});
       console.log(this.applyInfoArray);
       // 添加FormControl
       const control = <FormGroup>this.addFormGroup.controls['sqxx'];
       ////// 1. 创建FormControl
       const typeControl = new FormControl([null, Validators.required]);
       const numControl = new FormControl([null, Validators.required]);
       ///// 2. 设置默认值
       typeControl.setValue('');
       numControl.setValue('');
       //// 3. 添加FormControl至sqxx表单控件内
       control.addControl(uid1,typeControl);
       control.addControl(uid2,numControl);

    }

    // 生成唯一值
   getUID() {
       return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
          const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
          return v.toString(16);
      });
   }

}



    // 删除表单项
  delInfo(type, num) {
    if (this.infoArray.length > 1) {
      // 从申请信息记录数组中删除此项
      for (let i = 0; i < this.infoArray.length; i++) {
        if (this.infoArray[i].type===type && this.infoArray[i].num===num) {
          this.infoArray.splice(i, 1);
        }
      }
      const sqxxControl = <FormGroup>this.formGroup.controls['sqxx'];
      sqxxControl.removeControl(type);
      sqxxControl.removeControl(num);
    } else {
      this._msgService.warning('这已是最后一项,不可删除');
    }
  }

    // 最终获取数据
    getData() {
       // 构造动态表单信息
      const formDataValue = this.formGroup.value;
      const sqxxData = [];
      for (let i = 0; i < this.infoArray.length; i++) {
        const item = {
          num : formDataValue.sqxx[this.infoArray[i].num],
          type: formDataValue.sqxx[this.infoArray[i].type]
        };
        sqxxData.push(sqxxItem);
      }
       console.log(sqxxData);
    }

    // 验证表单

    validateForm() {
        this.isSqxxValid = true; // 保证和别的表单一同验证;
        for (const i in this.formGroup.controls) {
          form.controls[ i ].markAsDirty();
          form.controls[ i ].updateValueAndValidity();
        }
        // 验证是否通过
        if (form.valid) { // 验证通过
           //////////
        }

}



第二类:非嵌套表单


1. 非嵌套表单使用

1. 非嵌套表单动态添加删除


FormGroup 和 FormArray的区别

  • FormGroup
    跟踪一组 FormControl 实例的值和有效性状态。有对应的key值;添加删除对应的方法分别为: addControl / removeControl;
  • FormArray
    跟踪一个控件数组的值和有效性状态,控件可以是 FormControl、FormGroup 或 FormArray 的实例。无对应的key值;添加删除对应的方法分别为: push /removeAt;
原文地址:https://www.cnblogs.com/zero-zm/p/10421624.html