angular4 表單

1.模板式表單css

在html模板上控制html

指令對應的實例react

 

1.ngForm指令:標記表單,會隱式建立FormGroup類的實例,這個類表明表單數據模型,並存儲表單數據;數組

2.ngModel指令:標記單個字段,ngFrom指令會發現含有ngModel指令的標籤,並添加到表單數據模型中,使用該指令必須跟隨name屬性;瀏覽器

3.ngModelGroup指令:標記多個字段組合,表現形式是一個對象,如{name:"張三",pass:"123"};服務器

例子:app

<!--模板變量myForm指向ngForm對象-->
<form #myForm = "ngForm" (ngSubmit) = "onSubmit(myForm.value)">
  <div>用戶名:<input ngModel type="text" name="username"/></div>
  <!--ngModelGroup將字段嵌套成一個組-->
  <div ngModelGroup="passwordGroup">
     <div>密碼:<input ngModel type="password" name="password"/></div>
     <div>確認密碼:<input ngModel type="password" name="confirmPass"/></div>
  </div>
  <div>電話:<input ngModel type="text" name="mobile"/></div>
  <div><input type="submit" value="提交"/></div>
</form>

結果:異步

 

2.響應式表單angular4

在ts上控制表單數據,可用於動態生成表單ide

類對應的指令

formGroup:標記組,表單也屬於組,屬於屬性指令,須要加 [ ]

formGroupName:標記組,用於formGroup指令範圍內部

formControl:標記字段,屬於屬性指令,須要加 [ ],用於在formGroup指令範圍外部

formControlName:標記字段,用於formGroup指令範圍內部

formArrayName:標記數組,用於formGroup指令範圍內部

例子:

reactiveForm.html

<form [formGroup]="formModel" (submit)=onSubmit() novalidate>
  <div formGroupName="dateRange">
    起始日期:<input type="date" formControlName="from">
    截止日期:<input type="date" formControlName="to">
  </div>
  <div>
    <ul formArrayName="emails">
      <!-- 循環formArray數組,和下標 -->
      <li *ngFor="let e of this.formModel.get('emails').controls; let i=index;">
        <!-- formArray沒有key,全部使用屬性綁定[],值爲數組的下標 -->
        <input type="text" [formControlName]="i">
      </li>
    </ul>
    <button type="button" (click)="addEmail()">增長Email</button>
  </div>
  <button type="submit">保存</button>
</form>
<input type="text" [formControl]="username">

reactiveForm.ts

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

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

  //定義數據模型
  formModel : FormGroup = new FormGroup({
    dateRange : new FormGroup({
      from:new FormControl(),
      to:new FormControl()
    }),
    emails : new FormArray([
      new FormControl("a@aa.com"),
      new FormControl("b@bb.com"),
    ])
  });
  
 username:FormControl=new FormControl("張三"); 

  constructor() {}
  ngOnInit() {}

  onSubmit(){
    console.log(this.formModel.value);
  }
 
  addEmail(){
    let emails=this.formModel.get("emails") as FormArray;
    emails.push(new FormControl());
  }
}

 也能夠使用FormBuilder類來建立數據模型,上面代碼改爲:

 formModel : FormGroup;

  constructor(fb:FormBuilder){  
    //定義數據模型
    this.formModel  = fb.group({
      dateRange : fb.group({
        from:[''],
        to:['']
      }),
      emails : fb.array([
        ["a@aa.com"],
        ["b@bb.com"],
      ])
  });

 

3.響應式表單校驗

angular4提供了validator類的預約義校驗

  • required - 設置表單控件值是非空的

  • email - 設置表單控件值的格式是 email

  • minlength - 設置表單控件值的最小長度

  • maxlength - 設置表單控件值的最大長度

  • pattern - 設置表單控件的值需匹配 pattern 對應的模式

固然,也能夠進行自定義校驗

例子:

reactiveForm.html

<form [formGroup]="formModel" (ngSubmit) = "onSubmit()" novalidate>
  <div>用戶名:<input formControlName="username"/></div>
  
  <!-- 當驗證經過或者未點擊該字段時隱藏,狀態字段untouched=true表示未點擊,touched=true表示已點擊 -->
  <div [hidden]="formModel.get('username').valid || formModel.get('username').untouched">
    <!-- 1.在模板上硬編碼錯誤信息 -->
    <!-- [hidden]=false表示顯示錯誤信息,hasError(校驗失敗返回對象的key,校驗字段的name) -->
    <div [hidden]="!formModel.hasError('required','username')">
      用戶名是必填項
    </div>
    <div [hidden]="!formModel.hasError('minLength','username')">
      用戶名最小長度6
    </div>
</div>

  <div formGroupName="passwordsGroup">
     <div>密碼:<input formControlName="password"/></div>
     <!-- 包含在group中的hasError第二個參數爲數組[groupname,controlname] -->
     <div [hidden]="!formModel.hasError('minLength',['passwordsGroup','password'])">
        密碼最小長度是6
     </div>
     <div>確認密碼:<input formControlName="pconfirm"/></div>
     <div [hidden]="!formModel.hasError('equal','passwordsGroup')">
        {{formModel.getError('equal',passwordsGroup)?.passErrDesc}}
     </div>
  </div>
  

  <div>電話:<input formControlName="mobile"/></div>
  <!-- 當驗證沒有經過或者未改變該字段值時顯示 狀態字段pristine=ture表示未改變,dirty=ture表示已改變-->
  <div [hidden]="formModel.get('mobile').valid || formModel.get('username').pristine">
    <!-- 2.動態錯誤提示 -->
    <div [hidden]="!formModel.hasError('mobile','mobile')">
        {{formModel.getError('mobile')?.mobileErrDesc}}
    </div>
  </div>
  <div><input type="submit" value="提交"/></div>
</form>

reactiveForm.ts

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

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

  formModel:FormGroup;

  /**
   * 自定義手機號校驗
   * 返回值:正確返回 null
   *         錯誤返回 key:value(value能夠是對象錯誤key:錯誤信息,也能夠是任意值)
   * @param control 
   */
  mobileValidator(control:FormControl):any{
    var myreg = /^((0\d{2,3}-\d{7,8})|(1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}))$/; 
    let valid = myreg.test(control.value);
    console.log("mobile的校驗結果是"+valid);
    return valid ? null : {mobile:{mobileErrDesc:"密碼和確認密碼不匹配"}};
  }

  //自定義密碼組校驗
  equalValidatir(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:{passErrDesc:"密碼和確認密碼不匹配"}};
  }

  constructor(fb:FormBuilder) {
    //定義數據模型
    this.formModel = fb.group({
      //預約義校驗
      username:['',[Validators.required,Validators.minLength(6)]],
      mobile:['',this.mobileValidator],
      passwordsGroup:fb.group({
        password:[''],
        pconfirm:['']
      },{validator:this.equalValidatir})
    });
  }

  ngOnInit() {}

  onSubmit(){
    //整個表單校驗經過
    if(this.formModel.valid){
      console.log(this.formModel.value);
    }
  }
}

固然,有些校驗方法時通用的,因此咱們能夠提取出全局的校驗方法。

須要function聲明該方法,再經過 export 關鍵字暴露該方法。

validator.ts

import { FormControl, FormGroup } from "@angular/forms";

//自定義手機號碼組校驗
export function mobileValidator(control:FormControl):any{
    var myreg = /^((0\d{2,3}-\d{7,8})|(1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}))$/; 
    let valid = myreg.test(control.value);
    console.log("mobile的校驗結果是"+valid);
    return valid ? null : {mobile:{mobileErrDesc:"密碼和確認密碼不匹配"}};
}

//自定義密碼組校驗
export function equalValidatir(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:{passErrDesc:"密碼和確認密碼不匹配"}};
  }

異步校驗器

用來調用遠程的服務來校驗表單的值。異步校驗器跟普通的校驗器同樣,只不過返回的是一個可觀測的流

例子:

validator.ts

import { FormControl, FormGroup } from "@angular/forms";

//自定義手機號碼組校驗
export function mobileAsyncValidator(control:FormControl):any{
    var myreg = /^((0\d{2,3}-\d{7,8})|(1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}))$/; 
    let valid = myreg.test(control.value);
    console.log("mobile的校驗結果是"+valid);
    //Observable.of返回一個流,.delay(5000)表示延遲5秒,用來模擬服務器響應時間
    return Observable.of(valid ? null : {mobile:{mobileErrDesc:"密碼和確認密碼不匹配"}}).delay(5000);
}

reactiveForm.ts

constructor(fb:FormBuilder) {
    //定義數據模型
    this.formModel = fb.group({
      //預約義校驗
      username:['',[Validators.required,Validators.minLength(6)]],
      //異步校驗做爲第3個構造函數
      mobile:['',this.mobileValidator,this.mobileAsyncValidator],
      passwordsGroup:fb.group({
        password:[''],
        pconfirm:['']
      },{validator:this.equalValidatir})
    });
  }
<!--狀態字段pending=true表示正在進行校驗-->
<div [hidden]="!formModel.get('mobile').pending">
   正在校驗手機合法性
</div>

 

4.模板式表單校驗 

終端輸入命令$ ng g directive directive/mobileValidator  建立指令文件

將校驗方法定義成指令,以下

mobileValidator.directive.ts

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

//指令裝飾器
@Directive({
  selector: '[mobile]',//指令名稱
  //useValue:校驗方法名稱 ,multi:true:表示token爲NG_VALIDATORS的提供器可對應多個useValue
  providers:[{provide:NG_VALIDATORS,useValue:mobileValidator,multi:true}]
})
export class MobileValidatorDirective {
  constructor() { }
}

在模板中使用指令來校驗模板表單

templateForm.component.html

<!-- novalidate指令:不啓用瀏覽器默認的表單校驗,讓angualr的校驗指令不受干擾 -->
<form #myForm = "ngForm" (ngSubmit) = "onSubmit(myForm.value,myForm.valid)" novalidate>
  <!-- 使用angular預約義的指令required,minlength等來校驗表單 -->
  <div>用戶名:<input ngModel required minlength="6" name="username" type="text"/></div>
  
  <div ngModelGroup="passwordGroup" equal>
     <div>密碼:<input ngModel type="password" name="password"/></div>
     <div>確認密碼:<input ngModel type="password" name="confirmPass"/></div>
  </div>

  <!-- 定義input事件來控制是否顯示錯誤提示 -->
  <div>電話:<input ngModel mobile name="mobile" type="text" (input)="onMobileInput(myForm)"/></div>
  <!-- 接收模板的值判斷是否顯示錯誤提示 -->
  <div [hidden]="mobileValid || mobileUntouched">
    <!-- 使用myForm.form獲取表單對象 -->
    <div [hidden]="!myForm.form.hasError('mobile','mobile')">
      電話號碼不正確
    </div>
    <div>
  <div><input type="submit" value="提交"/></div>
</form>

templateForm.component.ts

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms/src/directives/ng_form';

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

  mobileValid:boolean=true;
  mobileUntouched:boolean=true;

  //點擊電話輸入框時,判斷mobile是否合法
  onMobileInput(form:NgForm){
    if(form){
      this.mobileValid = form.form.get("mobile").valid;
      this.mobileUntouched = form.form.get("mobile").untouched;
    }
  }

  onSubmit(value:any,valid:boolean){
    console.log(valid);
    console.log(value);
  }
}
相關文章
相關標籤/搜索