Angular8表單內置API窺探

建立

formControl

實例用於追蹤單個表單控件的值和驗證狀態
<section>
  <div nz-row nzJustify="start" nzGutter="16">
    <div nz-col nzSpan="8">
      <input nz-input type="text" [formControl]="projectName" placeholder="請輸入項目名稱">
      <span *ngIf="!projectName.valid">missing required!</span>
    </div>
  </div>
</section>
import { Component, OnInit } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-create-form',
  templateUrl: './create-form.component.html',
  styleUrls: ['./create-form.component.scss']
})
export class CreateFormComponent implements OnInit {
  projectName: FormControl;
  constructor() { }

  ngOnInit() {
    this.projectName = new FormControl('123');
  }
}

上述輸入控件綁定了一個formControl類型的初始值,未添加任何校驗規則,使用內置API添加規則、校驗等操做。css

projectNameValidate() {
    // 清除已有的驗證器
    this.projectName.clearValidators();
    // 添加新驗證器
    this.projectName.setValidators([Validators.required]);
    this.projectName.updateValueAndValidity();
  }
<div nz-col nzSpan="8">
      <button nz-button (click)="projectNameValidate()">驗證</button>
    </div>

FormGroup

跟蹤一組FormControl實例的值和有效性狀態
<section>
  <form nz-form [formGroup]="outlayGroup" (ngSubmit)="outlayGroupSubmit($event)">
    <div nz-row nzGutter="8" nzJustify="start">
      <div nz-col nzFlex="flex" nzSpan="6">
        <nz-form-item>
          <nz-form-label nzSpan="8" nzRequired>團建</nz-form-label>
          <nz-form-control nzSpan="16">
            <input nz-input type="text" formControlName="activity">
          </nz-form-control>
        </nz-form-item>
      </div>
      <div nz-col nzFlex="flex" nzSpan="6">
        <nz-form-item>
          <nz-form-label nzSpan="8" nzRequired>項目調研</nz-form-label>
          <nz-form-control nzSpan="16">
            <input nz-input type="text" formControlName="project">
          </nz-form-control>
        </nz-form-item>
      </div>
    </div>
    <div nz-row>
      <div nz-col nzSpan="8">
        <button nz-button type="submit">提交申請</button>
      </div>
    </div>
  </form>
</section>
outlayFormInit() {
  this.outlayGroup = new FormGroup({
    activity: new FormControl(null, [Validators.required]),
    project: new FormControl(null, [Validators.required])
  });
}

目前表單是響應式類型,默認change狀態進行校驗,且初始值均爲 空值(推薦使用null替代'')
如今需求有所變更,申請單默認團建費用初始值設爲1001,可是公司今年效益不是很好,要求團建費用不得大於1000.html

outlayFormInit() {
    this.outlayGroup = new FormGroup({
      activity: new FormControl(1001, [Validators.required, Validators.max(1000)]),
      project: new FormControl(null, [Validators.required])
    });
  }

若是咱們進入申請頁面,直接點擊提交申請,雖然不會提交上去,可是也不會有提示或者報紅效果,此刻須要咱們進行手動校驗表單內選項。數組

outlayGroupSubmit(event) {
    if (!this.outlayGroup.valid) {
      const controls = this.outlayGroup.controls;
      for (const key in controls) {
        if (controls.hasOwnProperty(key)) {
          const formField = controls[key];
          formField.markAsDirty();
          formField.updateValueAndValidity();
        }
      }
      return;
    }
    // submit to ...
  }

若是要針對其中某個formControl進行操做,要先獲取control再進行操做。app

this.outlayGroup.get('activity').markAsDirty();
this.outlayGroup.get('activity').updateValueAndValidity();

tip:不要忘記標記爲髒值!flex

FormArray

跟蹤一個控件數組的值和有效性狀態。
<section>
  <form nz-form [formGroup]="prosecuteForm" (ngSubmit)="prosecuteFormSubmit($event)">
    <div nz-row nzGutter="8" nzJustify="start">
      <div nz-col nzFlex="flex" nzSpan="6">
        <nz-form-item>
          <nz-form-label nzSpan="8" nzRequired>日期</nz-form-label>
          <nz-form-control nzSpan="16">
            <nz-date-picker formControlName="date"></nz-date-picker>
          </nz-form-control>
        </nz-form-item>
      </div>
      <div nz-col nzFlex="flex" nzSpan="6">
        <nz-form-item>
          <nz-form-label nzSpan="8" nzRequired>被告</nz-form-label>
          <nz-form-control nzSpan="16">
            <input nz-input type="text" formControlName="defendant">
          </nz-form-control>
        </nz-form-item>
      </div>
    </div>
    <div>
      <button nz-button (click)="addMembers()">繼續添加</button>
      原告團體:
      <div formArrayName="plaintiff">
        <div nz-row nzGutter="8">
          <div nz-col nzSpan="6" *ngFor="let control of plaintiff.controls;let i = index;">
            <nz-form-item>
              <nz-form-control nzSpan="16">
                <input type="text" nz-input [formControlName]="i">
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
      </div>
    </div>
    <div nz-row>
      <div nz-col nzSpan="8">
        <button nz-button type="submit">提交申請</button>
      </div>
    </div>
  </form>
</section>
get plaintiff() {
    return this.prosecuteForm.get('plaintiff') as FormArray;
  }
  prosecuteFormInit() {
    this.prosecuteForm = new FormGroup({
      date: new FormControl(null, [Validators.required]),
      defendant: new FormControl(null, [Validators.required]),
      plaintiff: new FormArray([
        new FormControl(2, [Validators.required])
      ])
    });
  }
  addMembers() {
    this.plaintiff.push(new FormControl(null,[Validators.required]));
  }
  prosecuteFormSubmit() {
    console.log(this.prosecuteForm);
    this.plaintiff.controls.forEach((control, index) => {
      control.markAsDirty();
      control.updateValueAndValidity();
    });
  }

FormArray 的數組元素爲 FormControl實例;從一組List內獲取指定Control 能夠經過at(index)獲取後進行各類操做,這個很重要;添加新的Control須要獲取到FromArray實例後push 而不是add方法。ui

FormBuilder

這是個可注入的服務提供者,用於建立響應式表單控件。

建立一個記錄公司信息的簡單表單this

<section>
  <form nz-form [formGroup]="enterprisesFormData">
    <div nz-row nzGutter="8">
      <div nz-col nzSpan="8">
        <nz-form-item>
          <nz-form-label nzSpan="6">企業名稱</nz-form-label>
          <nz-form-control nzSpan="18">
            <input type="text" nz-input formControlName="enterpriseName">
          </nz-form-control>
        </nz-form-item>
      </div>
      <div nz-col nzSpan="8">
        <nz-form-item>
          <nz-form-label nzSpan="6">企業地址</nz-form-label>
          <nz-form-control nzSpan="18">
            <input type="text" nz-input formControlName="enterpriseAddr">
          </nz-form-control>
        </nz-form-item>
      </div>
      <div nz-col nzSpan="8">
        <nz-form-item>
          <nz-form-label nzSpan="6">企業電話</nz-form-label>
          <nz-form-control nzSpan="18">
            <input type="text" nz-input formControlName="tel">
          </nz-form-control>
        </nz-form-item>
      </div>
    </div>
  </form>
</section>
enterprisesInit() {
    this.enterprisesFormData = this.fb.group({
      enterpriseName: ['', Validators.required],
      enterpriseAddr: [''],
      tel: ['']
    });
  }

使用這個服務建立表單比前面的三種方式都更加簡單、明瞭。spa

更新(值、狀態、添加、刪除等)

FormControl

this.projectName.setValue('456');
this.projectName.patchValue('789');
this.projectName.setValidators([Validators.required, Validators.minLength(5)]);
this.projectName.markAsDirty();
this.projectName.updateValueAndValidity();

formControl就是一個控件了,沒法添加和刪除code

FormGroup

outlayFormInit() {
    this.outlayGroup = new FormGroup({
      activity: new FormControl(1001, [Validators.required, Validators.max(1000)]),
      project: new FormControl(null, [Validators.required])
    });
    // 更新單個值
    this.outlayGroup.get('activity').setValue(2000);
    // 多個更新
    this.outlayGroup.patchValue({
      project: '11100001',
      activity: 0
    });
    // 添加
    this.outlayGroup.addControl('other', new FormControl(100,[Validators.max(99)]));
    this.outlayGroup.addControl('game', new FormControl(1000));
    // 移除
    this.outlayGroup.removeControl('game');
    // 狀態
    this.outlayGroup.get('other').markAsDirty();
    this.outlayGroup.get('other').updateValueAndValidity();
  }

FormArray

get plaintiff() {
    return this.prosecuteForm.get('plaintiff') as FormArray;
  }
  addMembers() {
    this.plaintiff.push(new FormControl(null, [Validators.required]));
  }

添加使用 this.plaintiff.push(new FormControl())
獲取使用 this.plaintiff.at(i);
移除使用 this.plaintiff.removeAt(i)
更新具體 Control控件和校驗 與 前面的API一致;component

FormBuilder

這玩意能夠建立任意類型控件,根據建立表單類型去使用對應的API;若是建立的是group類型,則與 FormGroup 同樣使用。

校驗

單個FormControl

直接使用

control.markAsDirty();
control.updateValueAndValidity();

整個form校驗

就是將整個表單進行挨個校驗的過程,通常爲表單的controls屬性值進行迭代校驗,動態表單可能須要迭代嵌套的邏輯。

outlayGroupSubmit(event) {
    if (!this.outlayGroup.valid) {
      const controls = this.outlayGroup.controls;
      for (const key in controls) {
        if (controls.hasOwnProperty(key)) {
          const formField = controls[key];
          formField.markAsDirty();
          formField.updateValueAndValidity();
        }
      }
      return;
    }
    // submit to ...
  }
相關文章
相關標籤/搜索