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>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扫描二维码关注公众号,回复: 4770076 查看本文章

状态字段

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>

猜你喜欢

转载自blog.csdn.net/weixin_44174685/article/details/85334482