您现在的位置:首页 >> 前端 >> 内容

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

时间:2017/8/15 8:54:00 点击:

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

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

表单有:

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

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

模板式表单,及其校验

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

<form action="/regist" method="post" #myForm = "ngForm" (ngSubmit) = "onSubmit(myForm.value, myForm.valid)" novalidate>
      <p>用户名:<input ngModel required minlength="6" name="username" type="text" (input)="onMobileInput(myForm)"></p>
   <p [hidden] = "mobileValid || mobileUntouched">
     <p [hidden] = "!myForm.form.hasError('required', 'username')">用户名是必填项</p>
     <p [hidden] = "!myForm.form.hasError('minlength', 'username')">用户名最小长度是六位</p>
   </p>
  <p>手机号:<input ngModel  mobile name = "mobile" type="number"></p>
    <p [hidden] = "!myForm.form.hasError('mobile', 'mobile')">请输入正确的手机号aaafffaa</p>
  <p ngModelGroup="passwordsGroup" equal>
    <p>密码:<input ngModel minlength="6"  name="password" type="password"></p>
    <p [hidden] = "!myForm.form.hasError('minlength', ['passwordsGroup', 'password'])">密码最小长度是6</p>
    <p>确认密码:<input ngModel name="pconfirm" type="password"></p>
    <p [hidden] = "!myForm.form.hasError('equal', 'passwordsGroup')">
      {{myForm.form.getError('equal', 'passwordsGroup')?.descs}}
    </p>
  </p>
  <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"
<p>用户名:<input ngModel required minlength="6" name="username" type="text" (input)="onMobileInput(myForm)"></p>

这段代码是为用户名的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可以输入多个邮箱
Angular4模板式表单、响应式表单、表单状态字段
第二列是属性绑定,用属性绑定语法即[]语法,fZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcm1hcnJhebK7xNzNqLn9yvTQ1MC0sPO2qDxiciAvPg0KRm9ybUNvbnRyb2yyu8Tc08PU2mZvcm1ncm91cMDvo6zU2mZvcm1Hcm91cMDv0qrTw2Zvcm1jb250cm9sbmFtZTwvcD4NCjxwcmUgY2xhc3M9"brush:java;"> <form [formGroup]="formModel" (submit)="onSubmit()"> <p>用户名:<input[class.hasError]="formModel.get('username').invalid && formModel.get('username').touched" type="text" formControlName="username"></p> <p [hidden] = "formModel.get('username').valid || formModel.get('username').untouched"> <p [hidden] = "!formModel.hasError('required', 'username')">用户名是必填项</p> <p [hidden] = "!formModel.hasError('minlength', 'username')">用户名最小长度是6</p> </p> <p>手机号<input type="text" formControlName="mobile"></p> <p [hidden] = "formModel.get('mobile').valid || formModel.get('mobile').pristine"> <p [hidden] = "!formModel.hasError('mobile', 'mobile')">请输入正确的手机号</p> </p> <p [hidden] = "!formModel.get('mobile').pending"> 正在校验手机号合法性 </p> <p formGroupName="passwordsGroup"> <p>密码<input type="password" formControlName="password"></p> <p [hidden] = "!formModel.hasError('minlength', ['passwordsGroup', 'password'])">密码最小长度是6</p> <p>确认密码<input type="password" formControlName="pconfirm"></p> <p [hidden] = "!formModel.hasError('equal', 'passwordsGroup')"> {{formModel.getError('equal', 'passwordsGroup')?.descs}} </p> </p> <button type="submit">注册</button> </form> <p> {{formModel.status}} </p>

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: "两次密码不一致"} };
}
  

用户名

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

 

密码最小长度是6

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,他的第一个参数表示初始值,第二个参数是校验器,可以有多个校验器写成数组的形式,第三个参数是异步校验器

最后看一下

表单的状态字段

Angular4模板式表单、响应式表单、表单状态字段
Touched untouched 表示用户是否获取过字段
字段被修改过 dirty是true pristine是false
字段正处于异步校验时pending为true

Tags:AN NG GU UL 
作者:网络 来源:眉目成书
  • 上一篇:前端工程化
  • 下一篇:arguments重载