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="width: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="width: 120px;"></td>
                  <td><input nz-input placeholder="工作量" [formControlName]="item.num" style="width: 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;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM