Angular表單處理

1.模板式表單

template-form.component.html

<form #myForm="ngForm" (ngSubmit)="onsubmit(myForm.value)">
  <div>用戶名:<input ngModel name="username" type="text"></div>
  <div>手機號:<input ngModel name="phone" type="text"></div>
  <div>郵編:<input type="number"></div>
  <div ngModelGroup="passwordsGroup">
    <div>密碼::<input ngModel name="password" type="password"></div>
    <div>確認密碼:<input ngModel name="pconfirm" type="password"></div>
  </div>
  <button type="submit">註冊</button>
</form>
<div>
  {{myForm.value | json}}
</div>

template-form.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-template-form',
  templateUrl: './template-form.component.html',
  styleUrls: ['./template-form.component.css']
})
export class TemplateFormComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }
  onsubmit(value: any){
    console.log(value);
  }
}

2.響應式表單

1.

reactive-form.component.html

<form [formGroup]="formModel" (submit)="onSubmit()">
  <div formGroupName="dateRange">
    起始日期:<input type="date">
    截止日期:<input type="date">
  </div>
  <div>
    <ul>
      <li>
        <input type="text">
      </li>
    </ul>
    <button type="button">增加Email</button>
  </div>
  <button type="submit">保存</button>
</form>

reactive-form.component.ts

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

@Component({
  selector: 'app-reactive-form',
  templateUrl: './reactive-form.component.html',
  styleUrls: ['./reactive-form.component.css']
})
export class ReactiveFormComponent implements OnInit {
  /*指定初始值 */
  username: FormControl = new FormControl('aaa');
  /*formModel:表示整個表單的數據*/
  formModel:FormGroup = new FormGroup({
    dateRange: new FormGroup({
      from: new FormControl(),
       to: new FormControl()
    })
  });
  emails: FormArray = new FormArray([
    new FormControl('[email protected]'),
    new FormControl('[email protected]')
  ])
  constructor() { }
  ngOnInit() {
  }
  onSubmit() {
    console.log(this.formModel.value);
  }
}

2.

reactive-regist.component.html

<form [formGroup]="formModel" (submit)="onSubmit()">
  <div>用戶名:<input type="text" formControlName="username"></div>
  <div>手機號:<input type="text" formControlName="mobile"></div>
  <div formGroupName="passwordsGroup">
    <div>密碼::<input type="text" formControlName="password"></div>
    <div>確認密碼:<input type="text" formControlName="pconfirm"></div>
  </div>
  <button type="submit">註冊</button>
</form>

reactive-regist.component.ts

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

@Component({
  selector: 'app-reactive-regist',
  templateUrl: './reactive-regist.component.html',
  styleUrls: ['./reactive-regist.component.css']
})
export class ReactiveRegistComponent implements OnInit {
  formModel: FormGroup;
  /*1.new 關鍵字實例化表單模型的類*/
  /*constructor() {
    this.formModel = new FormGroup({
      username: new FormControl(),
      mobile: new FormControl(),
      passwordsGroup: new FormGroup({
        password: new FormControl(),
        pconfirm: new FormControl()
      })
    })
  }*/
  /*2.FormBuilder配置表單模型*/
  constructor(fb: FormBuilder) {
    this.formModel = fb.group({
      username: [''],
      mobile: [''],
      passwordsGroup: fb.group({
        password: [''],
        pconfirm: ['']
      })
    })
  }
  ngOnInit() {
  }
  onSubmit(){
    console.log(this.formModel.value);
  }
}

3.表單校驗

3.1Angular校驗器

xxxx(control:AbstractControl):{ [key:string] :any} {
	Validators.xxx
	return null ;
}

3.2校驗響應式表單

reactive-regist.component.ts

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

@Component({
  selector: 'app-reactive-regist',
  templateUrl: './reactive-regist.component.html',
  styleUrls: ['./reactive-regist.component.css']
})
export class ReactiveRegistComponent implements OnInit {
  formModel: FormGroup;
  /*2.FormBuilder配置表單模型*/
  constructor(fb: FormBuilder) {
    this.formModel = fb.group({
      username: ['', [Validators.required, Validators.minLength(6)]],
      mobile: [''],
      passwordsGroup: fb.group({
        password: [''],
        pconfirm: ['']
      })
    })
  }
  onSubmit(){
    let isValid: boolean = this.formModel.get("username").valid;
    console.log("username的校驗結果是:"+isValid);
    let errors: any = this.formModel.get("username").errors;
    console.log("username的錯誤信息是:"+JSON.stringify(errors));
    console.log(this.formModel.value);
  }
  ngOnInit() {
  }
}

自定義校驗器

創建文件夾:validator–》ts文件:validators.ts
validators.ts

/**
 * Created by Administrator on 2019/1/3/003.
 */
import {AbstractControl, FormControl, FormGroup} from "@angular/forms";
import {of} from 'rxjs';
import {delay} from 'rxjs/operators';
/*全局的typescript的函數*/
export function  mobileValidator(control: AbstractControl) :{ [key: string] :any} {
  var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
  let valid = myreg.test(control.value);
  console.log("mobile的校驗結果是:"+valid);
  return valid ? null : {mobile:true};
}
/*異步校驗器:調用遠程的服務校驗表單的值,返回不是對象,是可觀測的流*/
export function  mobileAsyncValidator(control: AbstractControl) :{ [key: string] :any} {
  var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
  let valid = myreg.test(control.value);
  console.log("mobile的校驗結果是:"+valid);
  return of(valid ? null : {mobile: true}).pipe(
    delay(5000)
  );
}
export function equalValidator(group:FormGroup): any {
  let password:FormControl = group.get("password") as FormControl;
  let pconfirm:FormControl = group.get("pconfirm") as FormControl;
  let valid:boolean = (password.value === pconfirm.value);
  console.log("密碼校驗結果是:"+valid);
  return valid ? null : {equal: {describle:"密碼和確認密碼不匹配"}};
}

reactive-regist.component.ts

import { Component, OnInit } from '@angular/core';
import {AbstractControl, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {equalValidator, mobileAsyncValidator, mobileValidator} from "../validator/validators";
@Component({
  selector: 'app-reactive-regist',
  templateUrl: './reactive-regist.component.html',
  styleUrls: ['./reactive-regist.component.css']
})
export class ReactiveRegistComponent implements OnInit {
  formModel: FormGroup;
  /*2.FormBuilder配置表單模型*/
  constructor(fb: FormBuilder) {
    this.formModel = fb.group({
      username: ['', [Validators.required, Validators.minLength(6)]],
      /*異步校驗器可以作爲formControl第三個構造函數傳入模型*/
      mobile: ['', mobileValidator, mobileAsyncValidator],
      passwordsGroup: fb.group({
        password: ['', Validators.minLength(6)],
        pconfirm: ['']
      },{validator: equalValidator})
    })
  }
  onSubmit(){
    let isValid: boolean = this.formModel.get("username").valid;
    console.log("username的校驗結果是:"+isValid);
    let errors: any = this.formModel.get("username").errors;
    console.log("username的錯誤信息是:"+JSON.stringify(errors));
    if(this.formModel.valid){
      /*全部通過驗證*/
      console.log(this.formModel.value);
    }
  }
  ngOnInit() {
  }
}

reactive-regist.component.html

<form [formGroup]="formModel" (submit)="onSubmit()">
  <div>用戶名:<input type="text" formControlName="username"></div>
  <div [hidden]="!formModel.hasError('required','username')">
    用戶名是必填項
  </div>
  <div [hidden]="!formModel.hasError('minlength','username')">
    用戶名最小長度是6
  </div>
  <div>手機號:<input type="text" formControlName="mobile"></div>
  <div [hidden]="!formModel.hasError('mobile','mobile')">
    請輸入正確的手機號
  </div>
  <div formGroupName="passwordsGroup">
    <div>密碼::<input type="text" formControlName="password"></div>
    <div [hidden]="!formModel.hasError('minlength',['passwordsGroup','password'])">
      密碼最小長度是6
    </div>
    <div>確認密碼:<input type="text" formControlName="pconfirm"></div>
    <div [hidden]="!formModel.hasError('equal','passwordsGroup')">
      {{formModel.getError('equal','passwordsGroup')?.describle}}
    </div>
  </div>
  <button type="submit">註冊</button>
</form>
<!--異步校驗器-->
<div>
  {{formModel.status}}
</div>

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

狀態字段

touched、untouched
是否獲取過焦點

<div>用戶名:<input type="text" formControlName="username"></div>
  <div [hidden]="formModel.get('username').valid || formModel.get('username').untouched">
    <div [hidden]="!formModel.hasError('required','username')">
      用戶名是必填項
    </div>
    <div [hidden]="!formModel.hasError('minlength','username')">
      用戶名最小長度是6
    </div>
  </div>

pristine、dirty
是否改變過,修改過false,true

<div>手機號:<input type="text" formControlName="mobile"></div>
  <div [hidden]="formModel.get('mobile').valid || formModel.get('mobile').pristine">
    <div [hidden]="!formModel.hasError('mobile','mobile')">
        請輸入正確的手機號
    </div>
  </div>

pending

<div>手機號:<input type="text" formControlName="mobile"></div>
  <div [hidden]="formModel.get('mobile').valid || formModel.get('mobile').pristine">
    <div [hidden]="!formModel.hasError('mobile','mobile')">
        請輸入正確的手機號
    </div>
  </div>
  <div [hidden]="!formModel.get('mobile').pending">
    正在校驗手機號合法性
  </div>

字段處於異步校驗時,true

3.3校驗模板式表單

1.生成指令
–> ng g directive directives/mmobileValidator
–> ng g directive directives/equalValidator
mmobileValidator.directive.ts

import { Directive } from '@angular/core';
import {NG_VALIDATORS} from "@angular/forms";
import {mobileValidator} from "../validator/validators";
@Directive({
  selector: '[mobile]',
  providers: [{provide: NG_VALIDATORS, useValue: mobileValidator, multi: true}]
})
export class MmobileValidatorDirective {
  constructor() { }
}

equalValidator.directive.ts

import { Directive } from '@angular/core';
import {NG_VALIDATORS} from "@angular/forms";
import {equalValidator} from "../validator/validators";
@Directive({
  selector: '[equal]',
  providers: [{provide: NG_VALIDATORS, useValue: equalValidator, multi: true}]
})
export class EqualValidatorDirective {
  constructor() { }
}

template-form.component.ts

import { Component, OnInit } from '@angular/core';
import {NgForm} from "@angular/forms";

@Component({
  selector: 'app-template-form',
  templateUrl: './template-form.component.html',
  styleUrls: ['./template-form.component.css']
})
export class TemplateFormComponent implements OnInit {
  mobileValid: boolean =true;
  mobileUntouched: boolean=true;
  constructor() { }

  ngOnInit() {
  }
  onsubmit(value: any,valid: boolean){
    /*console.log(value);
    console.log(valid);*/
  }
  onMobileInput(form: NgForm){
    if(form){
      this.mobileValid = form.form.get("mobile").valid;
      this.mobileUntouched = form.form.get("mobile").untouched;
    }
  }
}

template-form.component.html

<!--novalidate:不要啓動瀏覽器默認的表單校驗-->
<form #myForm="ngForm" (ngSubmit)="onsubmit(myForm.value,myForm.valid)" novalidate>
  <div>用戶名:<input ngModel required minlength="6" name="username" type="text" (input)="onMobileInput(myForm)"></div>
  <div [hidden]="mobileValid || mobileUntouched">
    <div [hidden]="!myForm.form.hasError('required','username')">
      用戶名是必填項
    </div>
    <div [hidden]="!myForm.form.hasError('minlength','username')">
      用戶名最小長度是6
    </div>
  </div>
  <div>手機號:<input ngModel mobile name="mobile" type="text"></div>
  <div [hidden]="!myForm.form.hasError('mobile','mobile')">
    請輸入正確的手機號
  </div>
  <div>郵編:<input type="number"></div>
  <div ngModelGroup="passwordsGroup" equal>
    <div>密碼::<input ngModel minlength="6" name="password" type="password"></div>
    <div [hidden]="!myForm.form.hasError('minlength',['passwordsGroup','password'])">
      密碼最小長度是6
    </div>
    <div>確認密碼:<input ngModel name="pconfirm" type="password"></div>
    <div [hidden]="!myForm.form.hasError('equal','passwordsGroup')">
      {{myForm.form.getError('equal','passwordsGroup')?.describle}}
    </div>
  </div>
  <button type="submit">註冊</button>
</form>
<div>
  <!--{{myForm.value | json}}-->
</div>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章