建了個羣有興趣的朋友能夠加一下 QQ 羣:Angular 修仙之路(1)羣 - 153742079 (已滿),請加 Angular 修仙之路(2)羣 - 648681235。html
第一節 - 建立最簡單的輸入框git
第二節 - 添加簡單的驗證功能github
第三節 - 顯示驗證失敗的錯誤信息typescript
第四節 - 建立表單shell
第五節 - ngModelGroup簡介npm
第六節 - 表單添加驗證狀態樣式json
第七節 - 表單控件的狀態api
第八節 - 使用單選控件服務器
第九節 - 使用多選控件app
本教程的開發環境及開發語言:
安裝 Angular CLI (可選)
npm install -g @angular/cli
建立新的項目
ng new PROJECT-NAME
啓動本地服務器
cd PROJECT-NAME ng serve
Angular 4 中有兩種表單:
Template Driven Forms - 模板驅動式表單 (相似於 AngularJS 1.x 中的表單 )
Reactive Forms - 響應式表單
本文主要介紹 Template Driven Forms (模板驅動式表單) 的基礎知識,相關的知識點會以問答的形式進行介紹。
在 Angular 表單中,咱們經過 ngModel
指令來實現雙向綁定。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <input type="text" [(ngModel)]="username"> {{username}} `, }) export class AppComponent { username = 'semlinker'; }
目前 Angular 支持的內建 validators
以下:
required - 設置表單控件值是非空的
email - 設置表單控件值的格式是 email
minlength - 設置表單控件值的最小長度
maxlength - 設置表單控件值的最大長度
pattern - 設置表單控件的值需匹配 pattern 對應的模式
接下來咱們來添加最簡單的 必填
校驗。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <input type="text" required [(ngModel)]="username"> {{username}} `, }) export class AppComponent { username = 'semlinker'; }
在 Angular 中,咱們能夠經過 #userName="ngModel"
方式獲取 ngModel
對象,而後經過 userName.valid
判斷表單控件是否經過驗證。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <input type="text" required [(ngModel)]="username" #userName="ngModel"> {{userName.valid}} `, }) export class AppComponent { username = 'semlinker'; }
在 Angular 中,咱們能夠經過 #userName="ngModel"
方式獲取 ngModel
對象,而後經過該對象的 errors
屬性,來獲取對應驗證規則 (如 required, minlength 等) 的驗證狀態。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <input type="text" required minlength="3" [(ngModel)]="username" #userName="ngModel"> <hr> <div *ngIf="userName.errors?.required">請您輸入用戶名</div> <div *ngIf="userName.errors?.minlength"> 用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲 {{userName.errors?.minlength.actualLength}} </div> `, }) export class AppComponent { username = 'semlinker'; }
在 Angular 中,咱們能夠使用熟悉的 <form>
標籤來建立表單。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <form> <input type="text" required minlength="3" name="username" [(ngModel)]="username" #userName="ngModel"> <hr> <div *ngIf="userName.errors?.required">請您輸入用戶名</div> <div *ngIf="userName.errors?.minlength"> 用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲 {{userName.errors?.minlength.actualLength}} </div> <button type="submit">提交</button> </form> `, }) export class AppComponent { username = 'semlinker'; }
須要注意的是,在使用 <form>
標籤後,咱們的 username
輸入框,必須添加 name
屬性。
在 Angular 中,咱們能夠經過 #loginForm="ngForm"
方式獲取 ngForm
對象,而後經過 loginForm.value
來獲取表單的值。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm.value)"> <input type="text" required minlength="3" name="username" [(ngModel)]="username" #userName="ngModel"> <hr> <div *ngIf="userName.errors?.required">請您輸入用戶名</div> <div *ngIf="userName.errors?.minlength"> 用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲 {{userName.errors?.minlength.actualLength}} </div> <button type="submit">提交</button> {{loginForm.value | json}} </form> `, }) export class AppComponent { username = 'semlinker'; onSubmit(value) { console.dir(value); } }
ngModelGroup 指令是 Angular 表單中提供的另外一特殊指令,能夠對錶單輸入內容進行分組,方便咱們在語義上區分不一樣性質的輸入。例如聯繫人的信息包括姓名及住址,如今需對姓名和住址進行精細化信息收集,姓名可精細化成姓和名字,地址可精細化成城市、區、街等。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm.value)"> <fieldset ngModelGroup="user"> <input type="text" required minlength="3" name="username" [(ngModel)]="username" #userName="ngModel"> <hr> <div *ngIf="userName.errors?.required">請您輸入用戶名</div> <div *ngIf="userName.errors?.minlength"> 用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲 {{userName.errors?.minlength.actualLength}} </div> <input type="password" ngModel name="password"> </fieldset> <button type="submit">提交</button> <hr> {{loginForm.value | json}} </form> `, }) export class AppComponent { username = 'semlinker'; onSubmit(value) { console.dir(value); } }
以上代碼成功運行後,{{loginForm.value | json}}
的輸出結果:
{ "user": { "username": "semlinker", "password": "123" } }
在 Angular 表單中,若驗證經過則會在表單控件上添加 ng-valid
類,若驗證失敗則會在表單控件上添加 ng-invalid
類。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', styles: [` input.ng-invalid { border: 3px solid red; } input.ng-valid { border: 3px solid green; } ` ], template: ` <form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm.value)"> <fieldset ngModelGroup="user"> <input type="text" required minlength="3" name="username" [(ngModel)]="username" #userName="ngModel"> <hr> <div *ngIf="userName.errors?.required">請您輸入用戶名</div> <div *ngIf="userName.errors?.minlength"> 用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲 {{userName.errors?.minlength.actualLength}} </div> <input type="password" required ngModel name="password"> </fieldset> <button type="submit">提交</button> <hr> {{loginForm.value | json}} </form> `, }) export class AppComponent { username = 'semlinker'; onSubmit(value) { console.dir(value); } }
valid
狀態外,還包含哪些狀態?在 Angular 中表單控件有如下 6 種狀態,咱們能夠經過 #userName="ngModel"
方式獲取 ngModel
對象,進而獲取控件的狀態信息。具體狀態以下:
valid - 表單控件有效
invalid - 表單控件無效
pristine - 表單控件值未改變
dirty - 表單控件值已改變
touched - 表單控件已被訪問過
untouched - 表單控件未被訪問過
import { Component } from '@angular/core'; @Component({ selector: 'app-root', styles: [` input.ng-invalid { border: 3px solid red; } input.ng-valid { border: 3px solid green; } ` ], template: ` <form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm.value)"> <fieldset ngModelGroup="user"> <input type="text" required minlength="3" name="username" [(ngModel)]="username" #userName="ngModel"> <hr> <p>Name控件的valid狀態:{{userName.valid}} - 表示控件有效</p> <p>Name控件的invalid狀態:{{userName.invalid}} - 表示控件無效</p> <p>Name控件的pristine狀態:{{userName.pristine}} - 表示控件值未改變</p> <p>Name控件的dirty狀態:{{userName.dirty}} - 表示控件值已改變</p> <p>Name控件的touched狀態:{{userName.touched}} - 表示控件已被訪問過</p> <p>Name控件的untouched狀態:{{userName.untouched}} - 表示控件未被訪問過</p> <div *ngIf="userName.errors?.required">請您輸入用戶名</div> <div *ngIf="userName.errors?.minlength"> 用戶名的長度必須大於 {{userName.errors?.minlength.requiredLength}},當前的長度爲 {{userName.errors?.minlength.actualLength}} </div> <input type="password" required ngModel name="password"> </fieldset> <button type="submit">提交</button> <hr> {{loginForm.value | json}} </form> `, }) export class AppComponent { username = 'semlinker'; onSubmit(value) { console.dir(value); } }
在 Angular 中,咱們經過 <input name="***" type="radio">
方式添加單選控件。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <form #loginForm="ngForm"> Angular版本: <div *ngFor="let version of versions;"> <input [attr.id]="version" name="version" ngModel required [value]="version" type="radio"> <label [attr.for]="version">{{version}}</label> </div> <hr> {{loginForm.value | json}} </form> `, }) export class AppComponent { versions = ['1.x', '2.x', '3.x']; }
在 Angular 中,咱們經過 <select name="***">
方式添加多選控件。
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <form #loginForm="ngForm"> Angular版本: <select name="version" [ngModel]="versions[0]"> <option *ngFor="let version of versions;" [value]="version"> {{version}} </option> </select> <hr> {{loginForm.value | json}} </form> `, }) export class AppComponent { versions = ['1.x', '2.x', '3.x']; }
import { Component } from '@angular/core'; @Component({ selector: 'app-root', styles: [` select.ng-invalid + label:after { content: '<-- 請選擇版本!' } ` ], template: ` <form #loginForm="ngForm"> Angular版本: <div> <select name="version" [ngModel]="version" required> <option *ngFor="let version of versions;" [value]="version"> {{version}} </option> </select> <label></label> </div> <hr> {{loginForm.value | json}} </form> `, }) export class AppComponent { versions = ['','1.x', '2.x', '3.x']; }