MurabitoB

Angular Template Form

N 人看过

Angular 的表單可分為兩種,一種是 Template Form ,一種是 Reactive Form。

Template Form 與 Reactive Form 的差異在於 Template Form 會以模板驅動去進行驗證,相關驗證方式都是以在 html template 上面追加 directive 的方式進行驗證,例如 required

其餘 built-in 的 validator 可以參照:Angular - Validators

首先要引用 Template Form 的方法須先引入 FormsModule

@NgModule({

declarations: [

AppComponent

],

imports: [

BrowserModule,

FormsModule,

],

providers: [],

bootstrap: [AppComponent]

})

接著,在自己的 Component 寫一個簡單的表單,並且給希望綁定在表單的元素加上 nameprop 以及 ngModel 的 Directive。

下面範例是一個簡單的表單

在 form 的 tag 透過 ngSubmit event 可以抓住其原本的 submit event 。

此外可以透過在表單內宣告 一個 #form 的變數,來讓 component 可以引用表單的狀態及當前的值。

 <form (ngSubmit)="onSubmit()" #form="ngForm">
<div>
	<label for="username">Username</label>
	<input
	  type="text"
	  id="username"
	  class="form-control"
	  ngModel
	  name="username"
	  required>
  </div>
  <button
	class="btn btn-default"
	type="button"
	(click)="suggestUserName()">Suggest an Username</button>
<div class="radio" *ngFor="let gender of genders">
  <label>
	<input
	  type="radio"
	  name="gender"
	  ngModel
	  [value]="gender"
	  required>
	{{ gender }}
  </label>
</div>
<button
  class="btn btn-primary"
  type="submit"
  [disabled]="!form.valid">Submit</button>
 </form>

@ViewChild('f', { static: false }) signupForm: NgForm;
user = {
  username: '',
  gender: ''
};

onSubmit() {
  this.user.gender = this.signupForm.value.gender;
}

在表單進行驗證的過程中,掛有 ngModel 的 input 會附加一些 class

# true flase
點擊過 ng-invalid ng-untouched
值有變過 ng-dirty ng-pristine
值驗證通過 ng-valid ng-invalid

可以透過以上 class 進行 CSS 的設定來顯示錯誤訊息。

此外,如果要透過 Component 修改 form 的值,有以下兩種方式

  1. setValue
  2. patchValue

patchValue 可以只傳需要修改的內容,而 setValue 會覆蓋掉整個內容。

this.signupForm.form.patchValue({
 username: suggestedName
   });

單一元素的驗證檢查

如果要驗證單一的元素,並顯示一些錯誤訊息,特別是根據不同的狀況顯示不同的錯誤,可以透過存取 ngModel 的變數在 template 上,避免 Component 過度肥大。

<input
	  type="text"
	  id="username"
	  class="form-control"
	  ngModel
	  name="username"
	  #username="ngModel"
	  required>
<div *ngIf="username.errors?.required" class="alert alert-danger">Name is required.</div>
	  

分組

如果表單變得比較大可以透過 ngModelGroup 的 Directive 來結構化資料。

 <form (ngSubmit)="onSubmit()" #form="ngForm">
<div 
ngModelGroup="userData"
#userData="ngModelGroup">
	<label for="username">Username</label>
	<input
	  type="text"
	  id="username"
	  class="form-control"
	  ngModel
	  name="username"
	  required>
  </div>
  <button
	class="btn btn-default"
	type="button"
	(click)="suggestUserName()">Suggest an Username</button>
<div class="radi o" *ngFor="let gender of genders">
  <label>
	<input
	  type="radio"
	  name="gender"
	  ngModel
	  [value]="gender"
	  required>
	{{ gender }}
  </label>
</div>
<button
  class="btn btn-primary"
  type="submit"
  [disabled]="!form.valid">Submit</button>
 </form>