Angular8 form built-in API snoop

Posted Jun 4, 20206 min read

create

formControl

Instances are used to track the value and validation status of individual form controls

<section>
  <div nz-row nzJustify="start" nzGutter="16">
    <div nz-col nzSpan="8">
      <input nz-input type="text" [formControl]="projectName" placeholder="Please enter the project name">
      <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');
  }
}

The above input control is bound to an initial value of type formControl, without adding any verification rules, and using the built-in API to add rules, verification and other operations.

  projectNameValidate() {
    //clear existing validator
    this.projectName.clearValidators();
    //Add new validator
    this.projectName.setValidators([Validators.required]);
    this.projectName.updateValueAndValidity();
  }


 <div nz-col nzSpan="8">
      <button nz-button(click)="projectNameValidate()">Validate</button>
    </div>

FormGroup

Track the value and validity status of a group of FormControl instances

<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>Team building</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>Project research</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">Submit application</button>
      </div>
    </div>
  </form>
</section>

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

The form is currently responsive, the default change status is verified, and the initial value is empty(recommended to use null instead'')
Now the demand has changed, and the initial value of the group construction cost of the application form is set to 1001, but the company's benefit this year is not very good, and the group construction cost must not exceed 1000.

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

If we go to the application page and click submit application directly, although it will not be submitted, there will be no prompt or redemption effect. At this moment, we need to manually verify the options in the form.

 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 ...
  }

If you want to operate on one of the formControl, you need to get the control first.

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

tip:Don't forget to mark as dirty!

FormArray

Track the value and validity status of a control array.

<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>Date</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>Defendant</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()">Continue to add</button>
      Plaintiff Group:
      <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">Submit application</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();
    });
  }

The array element of the FormArray is the FormControl instance; obtaining the specified Control from a set of Lists can be done through at(index) and then perform various operations. This is very important; adding a new Control requires obtaining the FromArray instance and pushing instead of the add method.

FormBuilder

This is an injectable service provider for creating responsive form controls.

Create a simple form to record company information

<section>
  <form nz-form [formGroup]="enterprisesFormData">
    <div nz-row nzGutter="8">
      <div nz-col nzSpan="8">
        <nz-form-item>
          <nz-form-label nzSpan="6">Company name</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">Business address</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">Corporate phone</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:['']
    });
  }

Using this service to create forms is simpler and clearer than the previous three methods.

Update(value, status, addition, deletion, etc.)

FormControl

this.projectName.setValue('456');
this.projectName.patchValue('789');


this.projectName.setValidators([Validators.required, Validators.minLength(5)]);
this.projectName.markAsDirty();
this.projectName.updateValueAndValidity();

formControl is a control and cannot be added or deleted

FormGroup

outlayFormInit() {
    this.outlayGroup = new FormGroup({
      activity:new FormControl(1001, [Validators.required, Validators.max(1000)]),
      project:new FormControl(null, [Validators.required])
    });
    //Update a single value
    this.outlayGroup.get('activity').setValue(2000);
    //multiple updates
    this.outlayGroup.patchValue({
      project:'11100001',
      activity:0
    });
    //Add to
    this.outlayGroup.addControl('other', new FormControl(100,[Validators.max(99)]));
    this.outlayGroup.addControl('game', new FormControl(1000));
    //remove
    this.outlayGroup.removeControl('game');
    //status
    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]));
  }

Add and use this.plaintiff.push(new FormControl());
Get using this.plaintiff.at(i);
Remove the use of this.plaintiff.removeAt(i)
Update specific Control controls and checkout are consistent with the previous API;

FormBuilder

This kind of thing can create any type of control, and use the corresponding API according to the type of form created; if it is a group type, it is used like FormGroup.

check

Single FormControl

Use directly

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

Entire form verification

It is the process of verifying the entire form one by one, generally iteratively verifying the control attribute value of the form, dynamic form may need to iterate nested logic.

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 ...
  }