zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    Es module vs require
    phaser3 画虚线实现
    新的计划
    [转]Boostrap Table的refresh和refreshOptions区别
    Storing Java objects in MySQL blobs
    【转】Ubuntu下搜狗输入法突然无法输入中文
    团队作业六
    团队作业七
    团队作业四
    团队作业三
  • 原文地址:https://www.cnblogs.com/zero-zm/p/10421624.html
Copyright © 2011-2022 走看看