YouTube 地址:ng-conf-2017 - Angular Form Validation
Google Doc:PPT
目录
第一节 - 验证概述
第二节 - 设置基本的验证
第三节 - 即将到来的验证功能
第一节 - 验证概述
同步验证器
同步验证器函数
tambourineValidator(ctrl: AbstractControl): ValidationErrors | null { return ctrl.value === 'tambourine' ? null : {tambo: {expected: 'tambourine',actual: ctrl.value }}; }
异步验证器
异步验证器函数
myAsyncValidator(ctrl: AbstractControl): Observable<ValidationErrors|null> { return this._http.get(`my/endpoint?username=${ctrl.value}`) .map(resp => resp.json().exists ? {exists: true} : null); }
第二节 - 设置基本的验证
json-server 简介
json-server 用于基于 JSON 数据快速地创建本地模拟的 REST
API。
json-server 的安装
$ npm install -g json-server
json-server 的使用
$ json-server --watch bids.json
Angular CLI 代理配置
创建 proxy.conf.json
文件
{ "/bids": { "target": "http://localhost:3000","secure": false } }
更新 package.json
文件
{ "scripts": { "start": "ng serve --proxy-config proxy.conf.json",} }
创建 bids.json
文件
{ "bids": [ { "id": 1,"name": "Semlinker","bid": "10" } ] }
同步验证与异步验证示例
AppModule
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import {ReactiveFormsModule} from "@angular/forms"; import {HttpModule} from "@angular/http"; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ],imports: [ BrowserModule,HttpModule,ReactiveFormsModule ],providers: [ {provide: 'config',useValue: {databaseURL: 'http://localhost:3000'}} ],bootstrap: [AppComponent] }) export class AppModule { }
AppComponent
import {Component,OnInit,Inject} from '@angular/core'; import {FormGroup,FormControl,Validators,AbstractControl,ValidationErrors} from "@angular/forms"; import {Http} from "@angular/http"; import {Observable} from "rxjs/Observable"; import 'rxjs/add/operator/map'; interface Bid { id: number; name: string; bid: number } @Component({ selector: 'app-root',template: ` <ul *ngIf="bids"> <li *ngFor="let bid of bids"> {{bid.name}}: {{bid.bid}} </li> </ul> <div> <p>New Bid</p> <form [formGroup]="form"> <input type="text" placeholder="Name" formControlName="name"> <div class="errors" *ngIf="name.invalid && name.touched"> Name is required. </div> <input type="number" placeholder="Bid" formControlName="bid"> <div class="errors" *ngIf="bid.invalid && bid.touched"> <div *ngIf="bid.hasError('required')">Bid is required.</div> <div *ngIf="bid.hasError('toolow')"> Bid is too low,expect {{bid.errors.toolow.expected}},current value is {{bid.value}}. </div> </div> </form> </div> <hr> <button (click)="post()" [disabled]="form.invalid">POST BID</button> `,styles: [` input.ng-invalid.ng-touched { border-left: 5px solid red; } input.ng-valid.ng-touched { border-left: 5px solid forestgreen; } `] }) export class AppComponent implements OnInit{ bids: Bid[]; form = new FormGroup({ name: new FormControl('',Validators.required),bid: new FormControl('',Validators.required,this.minimumBid.bind(this)) }); constructor( private _http: Http,@Inject('config')private config) { } ngOnInit() { this._http.get(`${this.config.databaseURL}/bids`) .map(resp => resp.json()) .subscribe( res => this.bids = res) } // 异步验证器 minimumBid(ctrl: AbstractControl): Observable<ValidationErrors|null> { return this._http.get(`${this.config.databaseURL}/bids`) .map(resp => resp.json()) .map(bids => bids[bids.length - 1]) .map(bid => { return ctrl.value > bid.bid ? null : {toolow: {expected: bid.bid}} }); } get name() { return this.form.get('name'); } get bid() { return this.form.get('bid'); } // 新增Bid post() { let newBid = {...this.form.value,id: ++this.bids[this.bids.length - 1].id}; this._http.post(`${this.config.databaseURL}/bids`,newBid) .map(resp => resp.json()) .subscribe(resp => { this.bids.push(resp); }); this.form.reset(); } }
第三节 - 即将到来的验证功能
验证流程
流程一
流程二
验证管线
基于上面的内容我们能做什么
定制验证器链示例
// ValidatorChain 目前还不支持 export class AppComponent implements OnInit{ bids: Bid[]; form = new FormGroup({ name: new FormControl('',{chain: this.myChain.bind(this)}) }); myChain(ctrl: AbstractControl): ValidatorChain { return (obs) => { return obs.map(Validators.required) .switchMap(errs => errs ? Observable.of(errs) : this.minimumBid(ctrl)).startWith(PENDING) } }原文链接:https://www.f2er.com/angularjs/147050.html