1. 程式人生 > >Angular表單

Angular表單

Angular中表單分為兩種,一種是是模板驅動表,一種是響應式表單。以下分別對模板驅動表單,響應式表單的使用,表單的驗證做示例。

1. 模板驅動型表單

1.1模板表單的使用

要使用模板驅動行表單首先需要在根模組下面引入FormsModule,然後將FormsModule模組匯入到根模組的ngModule中的imports陣列中,這樣才能夠就能訪問模板驅動表單的所有特性,包括 ngModel

模組的引用

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core'
; import { FormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms'; import { Routes, RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; import { LoginComponent } from './login/login.component'; import { ReactiveFormComponent } from './reactive-form/reactive-form.component'
; import { HeroFormComponent } from './hero-form/hero-form.component'; import { RighsterFormComponent } from './righster-form/righster-form.component'; const routes: Routes = [ { path: 'heroForm', component: HeroFormComponent }, { path: 'loginForm', component: LoginComponent }, { path
: 'reactiveForm', component: ReactiveFormComponent }, { path: 'registerForm', component: RighsterFormComponent }, { path: '', redirectTo: 'heroForm', pathMatch: 'full' } ]; @NgModule({ declarations: [ AppComponent, LoginComponent, ReactiveFormComponent, HeroFormComponent, RighsterFormComponent ], imports: [ BrowserModule, FormsModule, ReactiveFormsModule, RouterModule.forRoot(routes) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }

1.2模板表單的詳細介紹

新建一個login元件用來寫一個註冊的模板表單

其中模板為

<form action="/regist" method="post" #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value)">
<div class="row"><label class="form-label">使用者名稱:</label><input type="text" name="user" ngModel></div>
<div class="row"><label class="form-label">手機號:</label><input type="text" name="phone" ngModel></div>
<div class="row"><label class="form-label">郵編:</label><input type="number" name="youbian" ngModel></div>
<div ngModelGroup="passGroup">
  <div class="row"><label class="form-label">密碼:</label><input type="password" name="password" ngModel></div>
  <div class="row"><label class="form-label">確認密碼:</label><input type="password" name="repassword" ngModel></div>
</div>

<div class="row"><button type="submit">註冊</button></div>
</form>
<div>{{ myForm.value | json }}</div>

ngForm:Angular 會在 <form> 標籤上自動建立並附加一個 NgForm 指令。

NgForm 指令為 form 增補了一些額外特性。 它會控制那些帶有 ngModel 指令和 name 屬性的元素,監聽他們的屬性(包括其有效性)。 它還有自己的 valid 屬性,這個屬性只有在它包含的每個控制元件都有效時才是真。

myForm是一個模板變數

ngModel用於雙向繫結,如上面的程式碼表單元素需要設定name屬性,也可以寫成另一種形式

<div class="row"><label class="form-label">使用者名稱:</label><input type="text" name="user" [(ngModel)]="user"></div>

ngModelGroup可以用來分組

ngSubmit表單提交事件

myForm.value可以獲取表單資料。

在表單中使用 ngModel 可以獲得比僅使用雙向資料繫結更多的控制權。它還會告訴你很多資訊:使用者碰過此控制元件嗎?它的值變化了嗎?資料變得無效了嗎?

NgModel 指令不僅僅跟蹤狀態。它還使用特定的 Angular CSS 類來更新控制元件,以反映當前狀態。 可以利用這些 CSS 類來修改控制元件的外觀,顯示或隱藏訊息。

狀態 為真時的 CSS 類 為假時的 CSS 類
控制元件被訪問過。 ng-touched ng-untouched
控制元件的值變化了。 ng-dirty ng-pristine
控制元件的值有效。 ng-valid ng-invalid

2. 響應式表單

2.1響應式表單簡介

響應式表單使用顯式的、不可變的方式,管理表單在特定的時間點上的狀態。對錶單狀態的每一次變更都會返回一個新的狀態,這樣可以在變化時維護模型的整體性。響應式表單是圍繞 Observable 的流構建的,表單的輸入和值都是通過這些輸入值組成的流來提供的,同時,也賦予你對資料進行同步訪問的能力。這種方式允許你的模板利用這些表單的“狀態變更流”,而不必依賴它們。

響應式表單與模板驅動的表單有著顯著的不同點。響應式表單通過對資料模型的同步訪問提供了更多的可預測性,使用 Observable 的操作符提供了不可變性,並且通過 Observable 流提供了變化追蹤功能。

2.2 響應式表單具體使用

要使用響應式表單,首先需要在@angular/forms包中匯入ReactiveFormsModule,並把它放到ngModule的imports陣列中去。

FormControl:

當使用響應式表單時,FormControl 是最基本的構造塊。要註冊單個的表單控制元件,請在元件中匯入 FormControl 類,並建立一個 FormControl 的新例項,把它儲存在類的某個屬性中。

FormGroup

正如 FormControl 的例項能讓你控制單個輸入框所對應的控制元件,FormGroup 可以跟蹤一組 FormControl 例項(比如一個表單)的表單狀態。當建立 FormGroup 時,其中的每個控制元件都會根據其名字進行跟蹤。

FormBuilder

當需要與多個表單打交道時,手動建立多個表單控制元件例項會非常繁瑣。FormBuilder 服務提供了一些便捷方法來生成表單控制元件。FormBuilder 在幕後也使用同樣的方式來建立和返回這些例項,用起來更簡單。 ,用 FormBuilder 來代替手工建立這些 FormControlFormGroup

FormArray

FormArrayFormGroup 之外的另一個選擇,用於管理任意數量的匿名控制元件。像 FormGroup 例項一樣,你也可以往 FormArray 中動態插入和移除控制元件,並且 FormArray 例項的值和驗證狀態也是根據它的子控制元件計算得來的。 不過,你不需要為每個控制元件定義一個名字作為 key,因此,如果你事先不知道子控制元件的數量,這就是一個很好的選擇。

表單部分模型更新

當修改包含多個控制元件的 FormGroup 的值時,你可能只希望更新模型中的一部分,而不是完全替換掉。

修補(Patch)模型值

對單個控制元件,你會使用 setValue() 方法來該控制元件設定新值。但當應用到 FormGroup 並打算整體設定該控制元件的值時,setValue() 方法會受到這個 FormGroup 結構的很多約束。patchValue() 方法就寬鬆多了,它只會替換表單模型中修改過的那些屬性,因為你只想提供部分修改。setValue() 中嚴格的檢查可以幫你捕獲複雜表單巢狀時可能出現的錯誤,而 patchValue() 將會默默地走向失敗。

eg:

 this.profileForm.patchValue({
    firstName: 'Nancy',
    address: {
      street: '123 Drew Street'
    }
  });

先舉一個不使用FormBuilder服務建立控制元件的方法

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

@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('[email protected]'),
      new FormControl('[email protected]'),
    ]
  )
  });
  username: FormControl = new FormControl('aa');
  constructor() { }

  ngOnInit() {
  }
  addEmail(): void {
    const emails = this.formModel.get('emails') as FormArray;
    emails.push(new FormControl());
  }
  onSubmit(): void {
    console.log(this.formModel);
  }

}

模板

<form [formGroup]="formModel" (submit)="onSubmit()">
  <div formGroupName="dateRange">
    起始日期: <input type="date" formControlName="from">
    截止日期: <input type="date" formControlName="to">
  </div>
  <div>
    <ul formArrayName="emails">
      <li *ngFor="let email of this.formModel.get('emails').controls;let i=index;">
        <input type="text" [formControlName]="i">
      </li>
    </ul>
    <button type="button" (click)="addEmail()">增加email</button>
  </div>
  <button type="submit">儲存</button>
</form>

再舉一個使用FormBulider服務建立表單控制元件的例子,生成一個註冊元件

import { Component, OnInit } from '@angular/core';
import {FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';
import { mobileValidator, equalValidator } from '../validator/validators';


@Component({
  selector: 'app-righster-form',
  templateUrl: './righster-form.component.html',
  styleUrls: ['./righster-form.component.css']
})
export class RighsterFormComponent implements OnInit {
  rigisterForm: FormGroup;
  isCanSubmit: boolean;
  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.createForm();
  }
  createForm() {
    this.rigisterForm = this.fb.group({
      username: ['', [Validators.required, Validators.minLength(6)]],
      mobile: ['', mobileValidator],
      passwordGroup: this.fb.group({
        password: ['', [Validators.minLength(6)]],
        pconfirm: ['']
      }, {validator: equalValidator})
    });
  }
  // 提交
  onSubmit() {
    const isValid: boolean = this.rigisterForm.get('username').valid;
    // console.log(isValid);
    // console.log( this.rigisterForm.get('username'));
    if (this.rigisterForm.valid) {
      console.log(this.rigisterForm.value);
    }
  }

}

其中關於驗證的可以先忽略;

模板程式碼:

<h2>使用者註冊</h2>
<form [formGroup]="rigisterForm" (submit)="onSubmit()">
  <div class="row">
    <label>使用者名稱:</label><input type="text" formControlName="username">
  </div>
  <div [hidden]="rigisterForm.get('username').valid || rigisterForm.get('username').untouched">
      <div [hidden]="!rigisterForm.hasError('required', 'username')">
          使用者名稱是必填項
        </div>
        <div [hidden]="!rigisterForm.hasError('minlength', 'username')">
          使用者名稱最小長度是6
        </div>
  </div>
  <div class="row">
    <label>手機號:</label><input type="text" formControlName="mobile">
  </div>
  <div [hidden]="rigisterForm.get('mobile').valid || rigisterForm.get('mobile').pristine">
      <div [hidden]="!rigisterForm.hasError('mobile', 'mobile')">
          請輸入正確的手機號碼
        </div>
  </div>

  <div formGroupName="passwordGroup">
    <div class="row">
      <label>密碼:</label><input type="password" formControlName="password">
    </div>
    <div [hidden]="!rigisterForm.hasError('minLength', ['passwordGroup', 'password'])">
      密碼長度最少6位
    </div>
    <div class="row">
      <label>確認密碼:</label><input type="password" formControlName="pconfirm">
    </div>
    <div [hidden]="!rigisterForm.hasError('equal', 'passwordGroup')">
        兩次密碼輸入不一致
    </div>
  </div>
  <div class="row">
    <button type="submit">提交</button>
  </div>
</form>
<p>{{ rigisterForm.status }}</p>

可以使用rigisterForm.get(formControlName).value獲取每個控制元件的值,

rigisterForm.value可以獲取整個表單的資料

rigisterForm.status可以獲取表單驗證是否通過,是表單所有的驗證規則。

3.表單驗證

3. 1模板驅動驗證

為了往模板驅動表單中新增驗證機制,你要新增一些驗證屬性,就像原生的 HTML 表單驗證器。 Angular 會用指令來匹配這些具有驗證功能的指令。

每當表單控制元件中的值發生變化時,Angular 就會進行驗證,並生成一個驗證錯誤的列表(對應著 INVALID 狀態)或者 null(對應著 VALID 狀態)。

eg:

<input id="name" name="name" class="form-control" 
      required minlength="4" appForbiddenName="bob"
      [(ngModel)]="hero.name" #name="ngModel" >

<div *ngIf="name.invalid && (name.dirty || name.touched)"
    class="alert alert-danger">

  <div *ngIf="name.errors.required">
    Name is required.
  </div>
  <div *ngIf="name.errors.minlength">
    Name must be at least 4 characters long.
  </div>
  <div *ngIf="name.errors.forbiddenName">
    Name cannot be Bob.
  </div>

</div>

3.2響應式表單驗證

在響應式表單中,真正的原始碼都在元件類中。不應該通過模板上的屬性來新增驗證器,而應該在元件類中直接把驗證器函式新增到表單控制元件模型上(FormControl)。然後,一旦控制元件發生了變化,Angular 就會呼叫這些函式。

驗證器函式

有兩種驗證器函式:同步驗證器和非同步驗證器。

  • 同步驗證器函式接受一個控制元件例項,然後返回一組驗證錯誤或 null。你可以在例項化一個 FormControl 時把它作為建構函式的第二個引數傳進去。
  • 非同步驗證器函式接受一個控制元件例項,並返回一個承諾(Promise)或可觀察物件(Observable),它們稍後會發出一組驗證錯誤或者 null。你可以在例項化一個 FormControl 時把它作為建構函式的第三個引數傳進去。

上面2.2中最後一個例子使用的就是響應式表單驗證。

自定義驗證器,2.2最後一個例子就有兩個自定義驗證器,mobileValidator和equalValidator分別驗證手機號和密碼,自定義驗證器程式碼如下:

import {FormGroup, FormControl } from '@angular/forms';
export function mobileValidator(control: FormControl): any {
    const myreg = /^1[0-9]{10}$/;
    const valid = myreg.test(control.value);
    console.log('mobile的校驗值為' + valid);
    return valid ? null : { mobile: true };
  }
  export function equalValidator(group: FormGroup): any {
    const pass = group.get('password') as FormControl;
    const pconfirm = group.get('pconfirm') as FormControl;
    const valid: boolean = (pass.value === pconfirm.value);
    console.log('密碼校驗結果' + valid);
    return valid ? null : { equal: true };
  }

自定義表單新增到響應式表單中很簡單,直接把這個函式放到FormControl就行了。

新增到模板驅動表單

在模板驅動表單中,你不用直接訪問 FormControl 例項。所以不能像響應式表單中那樣把驗證器傳進去,而應該在模板中新增一個指令。

相關推薦

Angular 校驗

result tex lar uil img 輸入 password value mod 1.html <form [formGroup]="formModel" (submit)="submit()"> <div> 用戶名

angular 操作

對象 用戶 loop 自動 .class 按鍵事件 有關 狀態 。。   一直沒有使用angular的表單驗證以及表單提交數據。只是用的input綁定值,另外最近的設計都是點擊後顯示錯誤,而不是自動顯示錯誤。所以錯誤顯示一直也沒有做。而表單的非法驗證可以直接解決這個問題。a

Angular——指令

src app 中國 tle 針對 checkbox $scope demo itl 基本介紹 這些指定只能針對input標簽 基本使用 <!DOCTYPE html> <html lang="en"> <head> <m

ngVerify - 更高效的 angular 驗證

man script 模板 所有 ams 範圍 依賴 mail 驗證 ngVerify v1.5.0 a easy Angular Form Validation plugin.簡潔高效的__angular表單驗證插件__ See how powerful it.看看它有多

angular知識點

業務 wrap group 數據模型 ali 封裝 reactive mco inter 原文   https://www.jianshu.com/p/c772d143e1fc 大綱   1、對表單的理解  2、模板驅動表單(Template Driven Forms)  

angular的使用實例

註入 數據 創建模板 In user ttr implement ide 等於 原文 https://www.jianshu.com/p/da1fd5396798 大綱   1、模板驅動表單的創建  2、響應式表單的創建  3、模板驅動型表單的自定義指令  4、響應式表單的

Angular處理

1.模板式表單 template-form.component.html <form #myForm="ngForm" (ngSubmit)="onsubmit(myForm.value)"> <div>使用者名稱:<input ngModel na

angular驗證之巢狀

正常情況下我們的瀏覽器不支援兩層的表單巢狀,所以,angular提供了ng-form來讓我們達到這樣的目的,主要用於部分表單提交,同時進行表單驗證。 <from> <ng

詳細angular驗證例項

          一個angular實現的表單驗證例子,包括使用者名稱已存在驗證,話不多說,看程式碼<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

Angular報錯:Can't bind to 'ngModel' since it isn't a known property of 'input'. (")"

錯誤資訊: core.js:1440 ERROR Error: Uncaught (in promise): Error: Template parse errors: Can't bind to 'ngModel' since it isn't a known prope

angular&服務

一、表單表單事件(keyup.enter)="" (blur)="" 表單模板 在模板驅動表單中,你只要匯入了FormsModule就不用對<form>做任何改動來使用FormsModule。<form #loginForm="ngForm"> log

Angular

Angular中表單分為兩種,一種是是模板驅動表,一種是響應式表單。以下分別對模板驅動表單,響應式表單的使用,表單的驗證做示例。 1. 模板驅動型表單 1.1模板表單的使用 要使用模板驅動行表單首先需要在根模組下面引入FormsModule,然後將

angular 驗證 遇到問題總結

 novalidate用在form標籤上,用來禁用 瀏覽器原生的表單校驗。             主要是樣式不夠美觀。  jquery外掛 用在 表單驗證裡,有時候選中的值不能對映到ngModel上。          可以通過在jquery選中的觸發的事件裡呼叫 ng

angular 元素,例如checkbox,radio,select等用法

Form 表單中有很多元素,最普遍的Input,CheckBox,Radio,Select等等。Angular的Form有什麼特殊之處呢? Input Input的屬性有: name 名字 type 型別(HTML5裡有的型別: number,url,email) ng-model 繫結的資料 requi

angular驗證,遠端驗證&&程式碼實現

定義驗證規則,驗證有效性 顯示驗證結果 禁用html5自帶驗證,novalidate=novalidate”“ 使用者輸入後,angular會依次呼叫驗證器進行驗證,全部成功時model會變成使用者輸

Angular 驗證類庫 ngx-validator 1.0 正式釋出

  背景介紹 之前寫了一篇 《如何優雅的使用 Angular 表單驗證》,結尾處介紹了統一驗證反饋的類庫  ngx-validator  ,由於這段時間一直在新模組做微前端以及相關業務元件庫,工具等開發,一直拖到現在,目前正式版 1.0 終於

angular js h5關於驗證的例子

checked tro mis scrip att sta error 自定義 account angular js表單驗證 <!DOCTYPE html><html><head lang="en"> <meta charse

Angular(ng指令操作)

rep class itl lock als 表達 tro [] pri html部分 ................................................. <!DOCTYPE html><html lang="en" ng-

Angular 4 必填字段提示CSS

表單 必填字段 提示 css.ng-valid[required].ng-dirty:not(form),.ng-valid.required.ng-dirty:not(form) { border-left: 5px solid #42A948;}.ng-valid[required].ng-pris

Angular Reactive Form-響應式驗證

規則 式表 length tps pla 示例 update require ont 內建驗證規則 Angular中提供了一些內建的Validators,這些驗證規則可以在Template-Driven或Reactive表單中使用。 目前 Angular 支持的內建 val