angular5 Reactive Form动态表单

Angular5 Reactive Form

根据最近的使用, 总结一下在ngx中使用reactive formcss

1. 建立表单

需求: 建立一个带验证的表单, 若是表单验证不经过则提交按钮disabled=truehtml

<!-- app.component.html -->

<form [formGroup]="form">

  <div class="form-group">
    <label for="">name: </label>
    <input type="text" formControlName="name">
  </div>
  <div class="form-group">
    <label for="">password: </label>
    <input type="password" formControlName="password">
  </div>

  <div class="form-group">
    <button type="submit" (click)="submit()" [disabled]="form.invalid">submit</button>
    <button type="button" (click)="reset()">reset</button>
  </div>
    
</form>
// app.component.ts

import {Component, OnInit} from '@angular/core';
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  name = 'app';

  form: FormGroup;

  constructor(
    private fb: FormBuilder
  ){}

  ngOnInit(){
    this.form = this.fb.group({
      name: ['', Validators.required],
      password: ['', [Validators.required, Validators.minLength(6)]]
    });
  }

  submit(){
    if(this.form.valid){
      console.log('submiting...')
    }else{
      console.log('form is not valid')
    }
  }

  reset(){
    this.form.reset();
  }
}

2. 自定义验证器

需求: 密码须要格式为数字字母下划线6-12位react

参考: Custom validatorstypescript

// app.component.ts

...

// 自定义密码验证
function ValidPwd(control: AbstractControl):any {
  const reg = /^\w{6,12}$/;
  if(reg.test(control.value)){
    // 经过验证时须要返回 null
    return null;
  }
  return {status: 'error', message: '密码格式为数字字母下划线6-12位'}
}

...
export class AppComponent implements OnInit {
...
  ngOnInit(){
    this.form = this.fb.group({
      name: ['', Validators.required],
      password: ['', [Validators.required, ValidPwd]]
    });
  }
...
}

3. 动态建立表单

需求: 表单增长朋友选项, 默认显示一个, 能够增长/删除api

<!-- app.component.html -->

<form [formGroup]="form">

  <div class="form-group">
    <label for="">name: </label>
    <input type="text" formControlName="name">
  </div>
    
  <div class="form-group">
    <label for="">password: </label>
    <input type="password" formControlName="password">
  </div>

  <ng-container *ngFor="let friend of friends.controls; let i=index">
    <div class="form-group">
      <label for="">friend(s): </label>
      <input type="text" [formControl]="friend">
      <span class="cursor-pointer hover-red" (click)="addFriend()" *ngIf="i===0">+</span>
      <span class="cursor-pointer hover-red" *ngIf="i!==0" (click)="removeFriend(i)">-</span>
    </div>
  </ng-container>

  <div class="form-group">
    <button type="submit" (click)="submit()" [disabled]="form.invalid">submit</button>
    <button type="button" (click)="reset()">reset</button>
  </div>

</form>
// app.component.ts

...

export class AppComponent implements OnInit {
  name = 'app';

  form: FormGroup;
  friends;

  constructor(
    private fb: FormBuilder
  ) {}

  ngOnInit() {
    this.form = this.fb.group({
      name: ['', Validators.required],
      password: ['', [Validators.required, ValidPwd]],
      friends: this.fb.array([this.createFriend()])
    });

    this.friends = this.form.get('friends') as FormArray;
  }

  /**
   * 动态建立表单
   * @returns {FormControl}
   */
  createFriend() {
    return this.fb.control('', Validators.required);
  }

  /**
   * 增长输入框
   */
  addFriend(): void {
    this.friends.push(this.createFriend());

  }

  /**
   * 移除输入框
   * @param {number} i
   */
  removeFriend(i: number): void {
    this.friends.removeAt(i);
  }

...

}

图片描述

4. standalone

需求: 增长单选框控制表单app

在Reactive表单中, 使用ngModel时, 会出现报错ide

Error: 
      ngModel cannot be used to register form controls with a parent formGroup directive.

报错中也提示了, 应该在input中增长[ngModelOptions]="{standalone: true}"ui

文档中是这么介绍的:this

standalone: Defaults to false. If this is set to true, the ngModel will not register itself with its parent form, and will act as if it's not in the form. This can be handy if you have form meta-controls, a.k.a. form elements nested in the <form> tag that control the display of the form, but don't contain form data.

如今表单变成这样:spa

<!-- app.component.html -->

<form [formGroup]="form">

  <div class="form-group">
    <label for="">name: </label>
    <input type="text" formControlName="name">
  </div>
  <div class="form-group">
    <label for="">password: </label>
    <input type="password" formControlName="password">
  </div>

  <ng-container
    *ngFor="let friend of friends.controls; let i=index">
    <div class="form-group">
      <label for="">friend(s): </label>
      <input type="text" [formControl]="friend">
      <span class="cursor-pointer hover-red" (click)="addFriend()" *ngIf="i===0">+</span>
      <span class="cursor-pointer hover-red" *ngIf="i!==0" (click)="removeFriend(i)">-</span>
    </div>
  </ng-container>

  <div class="form-group">
    <label for="">contactType: </label>
    mobile<input type="radio" value="0" [(ngModel)]="contactType" [ngModelOptions]="{standalone:true}">&emsp;
    landLine<input type="radio" value="1" [(ngModel)]="contactType" [ngModelOptions]="{standalone:true}">
  </div>

  <div class="form-group">
    <label for="">{{+contactType === 1?"landLine":"mobile"}}: </label>
    <input type="text" formControlName="contact">
  </div>

  <div class="form-group">
    <button type="submit" (click)="submit()" [disabled]="form.invalid">submit</button>
    <button type="button" (click)="reset()">reset</button>
  </div>

</form>

app.componen.ts中增长contactType变量, 表单实例中增长contact:

// app.component.ts

...

export class AppComponent implements OnInit {
  name = 'app';

  form: FormGroup;
  friends;
  contactType:number = 0;

  constructor(
    private fb: FormBuilder
  ) {}

  ngOnInit() {
    this.form = this.fb.group({
      name: ['', Validators.required],
      password: ['', [Validators.required, ValidPwd]],
      friends: this.fb.array([this.createFriend()]),
      contact: ['', Validators.required]
    });

    this.friends = this.form.get('friends') as FormArray;
  }

  /**
   * 动态建立表单
   * @returns {FormControl}
   */
  createFriend() {
    return this.fb.control('', Validators.required);
  }

  /**
   * 增长输入框
   */
  addFriend(): void {
    this.friends.push(this.createFriend());

  }

  /**
   * 移除输入框
   * @param {number} i
   */
  removeFriend(i: number): void {
    this.friends.removeAt(i);
  }

  submit() {
    if (this.form.valid) {
      console.log('submitting...');
    } else {
      console.log('form is not valid');
    }
  }

  reset() {
    this.form.reset();
  }
}
相关文章
相关标签/搜索