Angular4模板式表单、响应式表单、表单状态字段

时隔十多天我(独臂侠 灰常怀念两只胳膊~~(><)~~)又来了,之前是第三章的内容,今天先写*第七章表单处理*的内容吧,内容太多了,有必要记下来,如果有幸被看到欢迎指正^^

表单有:

     - 模板式表单
     - 响应式表单

模版式适合简单的场景, 响应式表单适合复杂的场景,如果不想让angular处理你的表单需要添加ngNoForm属性,如果不想让浏览器处理,则需要添加novalidate

模板式表单,及其校验

在指定了ngform指令的表单里,ngmodel是不需要[] 或()的,但必须指定name属性,下面这个代码片段是最终的模板式表单,

<form action="/regist" method="post" #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')">用户名最小长度是六位</div>
   </div>
  <div>手机号:<input ngModel  mobile name = "mobile" type="number"></div>
    <div [hidden] = "!myForm.form.hasError('mobile', 'mobile')">请输入正确的手机号aaafffaa</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')?.descs}}
    </div>
  </div>
  <button type="submit">注册</button>
</form>
onSubmit(value: any, valid: boolean) {
    console.log(valid);
    console.log(value);
  }
  mobileValid: boolean = true;
  mobileUntouched: boolean = true;
  onMobileInput(form: NgForm) {
    if ( form ) {
      this.mobileValid = form.form.get('username').valid;
      this.mobileUntouched = form.form.get('username').untouched;
      console.log(this.mobileValid + '----------------------' + this.mobileUntouched);
    }
  }

equal,mobile这些指令是在一个单独的文件中写
创建指令,directives是单独的文件夹

ng g directive  directives/mobileValidator
ng g directive  directives/equalValidator

mobileValidator.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 MobileValidatorDirective {

  constructor() { }

}

equalValidator.ts

import { Directive } from '@angular/core';
import {equalValidator} from '../validator/validators';
import {NG_VALIDATORS} from '@angular/forms';

@Directive({
  selector: '[equal]',
  providers: [{provide: NG_VALIDATORS, useValue: equalValidator, multi: true}]
})
export class EqualValidatorDirective {

  constructor() { }

}

这里要注意的就是providers 记得添加这个,还要注入validators里的校验方法,这个在下面写响应式表单的时候贴出来

下面解释代码的意思

(ngSubmit) = "onSubmit(myForm.value, myForm.valid)"

这行代码是在表单提交的时候把整个表单的信息,合法性传递给这个方法,用来处理表单,本例是在控制台打印出表单的信息和合法性

 onSubmit(value: any, valid: boolean) {
    console.log(valid);
    console.log(value);
  }

angular有针对表单的预定义的校验器Required ,minlength,maxlength,pattern(正则) …

required minlength="6"

<div>用户名:<input ngModel required minlength="6" name="username" type="text" (input)="onMobileInput(myForm)"></div>

这段代码是为用户名的input绑定一个方法,传入myForm,记得要传入 不然没办法获取表单信息,在此获取的是这个输入框的valid,untouched属性

  mobileValid: boolean = true;
  mobileUntouched: boolean = true;
  onMobileInput(form: NgForm) {
    if ( form ) {
      this.mobileValid = form.form.get('username').valid;
      this.mobileUntouched = form.form.get('username').untouched;
      console.log(this.mobileValid + '----------------------' + this.mobileUntouched);
    }
  }

响应式表单及其校验

FormGroup是多个FormControl的集合,若有一个formcontrol无效 则整个formgroup无效,FormArray 与FormGroup类似,但他有一个长度属性,他是一个可以增长的字段集合
FormGroup是固定的,如一个邮箱输入,用户不止一个邮箱,用formarray可以输入多个邮箱
这里写图片描述
第二列是属性绑定,用属性绑定语法即[]语法,formarray不能通过属性来绑定
FormControl不能用在formgroup里,在formGroup里要用formcontrolname

<form [formGroup]="formModel" (submit)="onSubmit()">
  <div>用户名:<input[class.hasError]="formModel.get('username').invalid && formModel.get('username').touched" 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>
  <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>
  <div formGroupName="passwordsGroup">
    <div>密码<input type="password" formControlName="password"></div>
    <div [hidden] = "!formModel.hasError('minlength', ['passwordsGroup', 'password'])">密码最小长度是6</div>
    <div>确认密码<input type="password" formControlName="pconfirm"></div>
    <div [hidden] = "!formModel.hasError('equal', 'passwordsGroup')">
      {{formModel.getError('equal', 'passwordsGroup')?.descs}}
    </div>
  </div>
  <button type="submit">注册</button>
</form>
<div>
  {{formModel.status}}
</div>
import { Component, OnInit } from '@angular/core';
import {AbstractControl, FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
import {equalValidator, mobileAsyncValidator, mobileValidator} from '../validator/validators';
import {validate} from "codelyzer/walkerFactory/walkerFn";

@Component({
  selector: 'app-reactive-regist',
  templateUrl: './reactive-regist.component.html',
  styleUrls: ['./reactive-regist.component.css']
})
export class ReactiveRegistComponent implements OnInit {
formModel: FormGroup;
  constructor(fb: FormBuilder) {
    this.formModel = fb.group({
      username: ['', [Validators.required, Validators.minLength(6)]],
      mobile: ['', mobileValidator, mobileAsyncValidator],
      passwordsGroup: fb.group({
        password: ['', Validators.minLength(6)],
        pconfirm: ['']
      }, {validator: equalValidator})
    });
  }
onSubmit() {
    let isValid: boolean = this.formModel.get("mobile").valid;
    console.log("mobile的检验结果" + isValid);
    let errors: any = this.formModel.get("mobile").errors;
    console.log("mobile的错误信息是" + JSON.stringify(errors));
    if (this.formModel.value) {
      console.log(this.formModel.value);
    }
}
  ngOnInit() {
  }

}

validator.ts


import {FormControl, FormGroup} from "@angular/forms";
import {Observable} from "rxjs/Observable";
import {observable} from "rxjs/symbol/observable";
export function mobileValidator(control: FormControl):  any {
  var myreg =  /^1[3|4|5|7|8][0-9]{9}$/;
  let valid = myreg.test(control.value);
  console.log("mobile的校验结果是" + valid);
  return valid ? null : {mobile : true};
}
export function mobileAsyncValidator(control: FormControl):  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 observable.of(valid ? null : {mobile : true}).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: {descs: "两次密码不一致"} };
}
  <div>用户名<input[class.hasError]="formModel.get('username').invalid && formModel.get('username').touched" type="text" formControlName="username"></div>

这段代码动态地为input添加了样式 只有在后面表达式为真时才显示样式,需要注意的是输入密码和确认密码这里

 <div [hidden] = "!formModel.hasError('minlength', ['passwordsGroup', 'password'])">密码最小长度是6</div>
export class ReactiveRegistComponent implements OnInit {
formModel: FormGroup;
  constructor(fb: FormBuilder) {
    this.formModel = fb.group({
      username: ['', [Validators.required, Validators.minLength(6)]],
      mobile: ['', mobileValidator, mobileAsyncValidator],
      passwordsGroup: fb.group({
        password: ['', Validators.minLength(6)],
        pconfirm: ['']
      }, {validator: equalValidator})
    });
    // this.formModel = new FormGroup({
    //   username: new FormControl(),
    //   mobile: new FormControl(),
    //   passwordsGroup: new FormGroup({
    //     password: new FormControl(),
    //     pconfirm: new FormControl()
    //   })
    // });
  }

后面注释的部分是另外一种写法 可以加参数,表示的是初始值

username: new FormControl("aaa"),
 username: ['aaa', [Validators.required, Validators.minLength(6)]],

第一个方法里面需要注入FormBuilder,他的第一个参数表示初始值,第二个参数是校验器,可以有多个校验器写成数组的形式,第三个参数是异步校验器

最后看一下

表单的状态字段

这里写图片描述
Touched untouched 表示用户是否获取过字段
字段被修改过 dirty是true pristine是false
字段正处于异步校验时pending为true

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值