2023/02/16——Angular 动态增减表单项

文章展示了如何在Angular应用中创建一个响应式表单,包括使用FormBuilder来定义FormArray类型的子控件,用于动态添加和移除strike_schedules和instrument_ids。同时,文章还涵盖了表单初始化赋值和校验状态的处理方法。
摘要由CSDN通过智能技术生成

先创建一个响应式表单

// 注意:此处只贴出部分相关代码
import { FormGroup, FormBuilder, FormArray, FormControl } from '@angular/forms';

export class FormComponent implements OnInit{
  public form: FormGroup;

  constructor(
    private fb: FormBuilder,
  ) {
    this.createForm();
  }

  ngOnInit(): void {
  }

  private createForm() {
    this.form = this.fb.group({
        // 针对场景一定义一个子控件,类型为 FormArray
        strike_schedules: this.fb.array([]),
       // 针对场景二定义一个子控件,类型为 FormArray
        instrument_ids: this.fb.array([]),
    });
    // 初始化时增加一项
    this.addStrikeScheduleItem(); 
    this.addInstrumentIdItem();
  }

   /**
   * 往 strike_schedules FormArray 中 push 一个 FormControl
   */
  private newStrikeScheduleItem(): FormControl {
    return this.fb.control(null);
  }
  get strikeSchedules(): FormArray {
    return this.form.get('strike_schedules') as FormArray;
  }

  public addStrikeScheduleItem() {
    this.strikeSchedules.push(this.newStrikeScheduleItem());
  }

  public removeStrikeScheduleItem(index: number) {
    this.strikeSchedules.removeAt(index);
  }

   /**
   * 往 instrument_ids FormArray 中 push 一个 FormGroup
   */
  private newInstrumentIdItem(): FormGroup {
    return this.fb.group({
      code: [null, Validators.required],
      scheme: [null, Validators.required],
    });
  }

  get instrumentIds(): FormArray {
    return this.form.get('instrument_ids') as FormArray;
  }

  public addInstrumentIdItem() {
    this.instrumentIds.push(this.newInstrumentIdItem());
  }

  public removeInstrumentIdItem(index: number) {
    this.instrumentIds.removeAt(index);
  }


}

form.components.html

<form nz-form [formGroup]="form" novalidate class="tiny-form">
    <!-- 动态增减 strike schedule -->
      <div formArrayName="strike_schedules" class="p-10 pr-15" >
                <div nz-row nzJustify="space-between">
                    <h4 nz-col class="text-16 text-bold">strike schedule</h4>
                    <button nz-col nz-button nzType="primary" nzGhost nzSize="small" (click)="addStrikeScheduleItem()">
                        <i nz-icon nzType="plus" nzTheme="outline"></i>
                    </button>
                </div>
                <nz-form-item nz-row nzJustify="space-between"
                    *ngFor="let item of strikeSchedules.controls; index as scheduleIndex">
                    <nz-form-control nz-col nzSpan="24">
                        <nz-date-picker nzSize="small" class="schedule-date" [nzFormat]="showDateFormatter"
                            [formControl]="strikeSchedules.controls[scheduleIndex]">
                        </nz-date-picker>
                        <button nz-button nzType="primary" nzDanger nzGhost nzSize="small"
                            (click)="removeStrikeScheduleItem(scheduleIndex)">
                            <i nz-icon nzType="minus" nzTheme="outline"></i>
                        </button>
                    </nz-form-control>
                </nz-form-item>
      </div>

     <!-- 动态增减 instrument ids -->
        <div formArrayName="instrument_ids" class="mb-5 mt-10">
            <ng-container *ngFor="let item of instrumentIds.controls; index as i">
                <nz-form-item [formGroupName]="i" class="mt-5">
                    <nz-form-label nzSpan="10" nzRequired>
                        <ng-container *ngIf="i === 0">instrument ids</ng-container>
                    </nz-form-label>
                    <nz-form-control nzSpan="14">
                        <nz-input-group nzSize="small">
                            <div nz-row>
                                <div nz-col nzSpan="10">
                                    <nz-select formControlName="scheme" [nzShowSearch]="true" nzSize="small"
                                        class="full-width">
                                        <nz-option *ngFor="let item of metaList?.instrument_id_schema_bond"
                                            [nzLabel]="item" [nzValue]="item">
                                        </nz-option>
                                    </nz-select>
                                </div>
                                <div nz-col nzSpan="14" class="pl-10 flex-space-between">
                                    <input type="text" nz-input formControlName="code" />
                                    <div class="pl-5 text-right" *ngIf="!ifDetail">
                                        <button *ngIf="i === 0" nz-button nzType="primary" nzGhost nzSize="small"
                                            (click)="addInstrumentIdItem()">
                                            <i nz-icon nzType="plus" nzTheme="outline"></i>
                                        </button>
                                        <button *ngIf="i !== 0" nz-button nzType="primary" nzDanger nzGhost
                                            nzSize="small" (click)="removeInstrumentIdItem(i)">
                                            <i nz-icon nzType="minus" nzTheme="outline"></i>
                                        </button>
                                    </div>
                                </div>
                            </div>
                        </nz-input-group>
                    </nz-form-control>
                </nz-form-item>
            </ng-container>
        </div>
</form>

formArray初始化赋值

  // 注意:此处 detailInfo.strike_schedules = ['2021-10-25', ...]
  // detailInfo.instrument_ids = [{code: '', scheme: ''}, ...]
  private initForm(detailInfo) {
    // strike_schedules
    if (detailInfo.strike_schedules.length) {
      this.strikeSchedules.clear();
      structuredDetail.strike_schedules.map((item, index, arr) => {
        this.strikeSchedules.push(this.newStrikeScheduleItem());
      });
    }
    // instrument_ids
    if (detailInfo.instrument_ids.length) {
      this.instrumentIds.clear();
      structuredDetail.instrument_ids.map((item, index, arr) => {
        this.instrumentIds.push(this.newInstrumentIdItem());
      });
    }
    this.form.patchValue(detailInfo);
  }

formArray 表单校验状态提示

public submit() {
    if (this.form.valid) {
      this.httpRequest();
    } else {
      this.formMarkAsDirtyCallback(this.form);
      this.messageService.error('the form is invalid');
      }
  }

  /**
   * 触发表单校验状态
   */
  private formMarkAsDirtyCallback(form) {
    for (const key in form.controls) {
      if (form.controls.hasOwnProperty(key)) {
        form.controls[key].markAsDirty();
        form.controls[key].updateValueAndValidity();
        // 如果 controls.key 里面还有 controls,则子控件类型可能为 FormGroup 或者 FormArray
        if (form.controls[key].hasOwnProperty('controls')) {
          if (form.controls[key]['length']) {
            // 如果 controls.key.length 不是 undefined,则该控件为 FormArray
            const formArr = form.get(key) as FormArray;
            for (const formArrIndex in formArr.controls) {
              if (formArr.controls.hasOwnProperty(formArrIndex)) {
                // 标记 FormArray 里面的 control
                const element = formArr.controls[formArrIndex] as FormGroup;
                this.formMarkAsDirtyCallback(element);
              }
            }
          } else {
            // 如果没有 controls.key.length 属性,则是 FormGroup 类型,此时重新循环校验
            this.formMarkAsDirtyCallback(form.controls[key]);
          }
        }
      }
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值