1. 程式人生 > >angular2-模板驅動表單

angular2-模板驅動表單

guide 組件 emp not otto 再次 雙向數據綁定 記得 ini

app.module.ts 導入 FormsModule

import { NgModule }      from ‘@angular/core‘;
import { BrowserModule } from ‘@angular/platform-browser‘;
import { FormsModule }   from ‘@angular/forms‘;
 
import { AppComponent }  from ‘./app.component‘;
import { HeroFormComponent } from ‘./hero-form.component‘;
 
@NgModule({
  imports: [
    BrowserModule,
    FormsModule
], declarations: [ AppComponent, HeroFormComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }

如果某個組件、指令或管道是屬於imports中所導入的某個模塊的,那就不能再把它再聲明到本模塊的declarations數組中。 如果它是你自己寫的,並且確實屬於當前模塊,才應該把它聲明在declarations數組中。

containerform-groupform-controlbtn類來自 Twitter Bootstrap。純粹是裝飾。 我們使用 Bootstrap 來美化表單。

Angular 不需要containerform-groupform-controlbtn類, 或者外部庫的任何樣式。Angular 應用可以使用任何 CSS 庫…… ,或者啥都不用

<form #heroForm="ngForm">
<div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name"> </div> <div class="form-group"> <label for="alterEgo">Alter Ego</label> <input type="text" class="form-control" id="alterEgo" [(ngModel)]="model.alterEgo" name="alterEgo"> </div> <div class="form-group"> <label for="power">Hero Power</label> <select class="form-control" id="power" required [(ngModel)]="model.power" name="power"> <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option> </select> </div>

  

NgForm:

什麽是NgForm指令? 但我們明明沒有添加過NgForm指令啊!

Angular替你做了。Angular會在<form>標簽上自動創建並附加一個NgForm指令。

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

<input>標簽還添加了name屬性 (attribute),並設置為 "name",表示英雄的名字。 使用任何唯一的值都可以。

當在表單中使用[(ngModel)]時,必須要定義name屬性。

內部,Angular 創建了一些FormControl,並把它們註冊到NgForm指令,再將該指令附加到<form>標簽。 註冊每個FormControl時,使用name屬性值作為鍵值

  • 每個 input 元素都有id屬性,label元素的for屬性用它來匹配到對應的輸入控件。

  • 每個 input 元素都有name屬性,Angular 表單用它註冊控件。

通過 ngModel 跟蹤修改狀態與有效性驗證

ngModel可以獲得比僅使用雙向數據綁定更多的控制權。它還會告訴我們很多信息:用戶碰過此控件嗎?它的值變化了嗎?數據變得無效了嗎?

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

狀態

為真時的 CSS 類

為假時的 CSS 類

控件被訪問過。

ng-touched ng-untouched

控件的值變化了。

ng-dirty ng-pristine

控件的值有效。

ng-valid ng-invalid

例子:往姓名<input>標簽上添加名叫 spy 的臨時模板引用變量, 然後用這個 spy 來顯示它上面的所有 CSS 類

<input type="text" class="form-control" id="name"
  required
  [(ngModel)]="model.name" name="name"
  #spy>
<br>TODO: remove this: {{spy.className}}
  • 查看輸入框,但別碰它: 技術分享
  • 點擊輸入框,然後點擊輸入框外面。: 技術分享
  • 在名字的末尾添加些斜杠。技術分享
  • 刪除名字。技術分享

(ng-valid | ng-invalid)這一對是我們最感興趣的。當數據變得無效時,我們希望發出強力的視覺信號, 還想要標記出必填字段。可以通過加入自定義 CSS 來提供視覺反饋

輸入框的左側添加帶顏色的豎條,用於標記必填字段和無效輸入

技術分享

添加兩個樣式來實現這一效果

.ng-valid[required], .ng-valid.required  {
  border-left: 5px solid #42A948; /* green */
}

.ng-invalid:not(form)  {
  border-left: 5px solid #a94442; /* red */
}

  

顯示和隱藏驗證錯誤信息

//template
<label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name" #name="ngModel"> <div [hidden]="name.valid || name.pristine" class="alert alert-danger"> Name is required </div>
<button type="button" class="btn btn-default" (click)="newHero()">New Hero</button>


//ts
newHero() { this.model = new Hero(42, ‘‘, ‘‘); }

 

當控件是有效的 (valid) 全新的 (pristine) ,隱藏消息。 “全新的”意味著從它被顯示在表單中開始,用戶還從未修改過它的值。

input 創建了名叫name的變量,並且賦值為 "ngModel"( 指令的 exportAs 屬性告訴 Angular 如何鏈接模板引用變量到指令。 這裏把name設置為ngModel是因為ngModel指令的exportAs屬性設置成了 “ngModel”)

點擊 New Hero 按鈕,表單被清空了。 輸入框左側的必填項豎條是紅色的.

問題:

輸入名字,再次點擊 New Hero 按鈕。 這次,出現了錯誤信息!為什麽?我們不希望顯示新(空)的英雄時,出現錯誤信息。

使用瀏覽器工具審查這個元素就會發現,這個 name 輸入框並不是全新的。 表單記得我們在點擊 New Hero 前輸入的名字。 更換了英雄並不會重置控件的“全新”狀態

我們必須清除所有標記,在調用 newHero() 方法後調用表單的 reset() 方法即可 (click)="newHero(); heroForm.reset()"

提交表單

<form (ngSubmit)="onSubmit()" #heroForm="ngForm">

<button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>

切換兩個表單區域(額外的獎勵)

把表單包裹進<div>中,再把它的hidden屬性綁定到HeroFormComponent.submitted屬性。

<div [hidden]="submitted">
  <h1>Hero Form</h1>
  <form (ngSubmit)="onSubmit()" #heroForm="ngForm">

  </form>
</div>

開始就是可見的,因為submitted屬性是 false,直到提交了這個表單。

submitted = false;

onSubmit() { this.submitted = true; }

當點擊 Submit 按鈕時,submitted標誌會變成 true,並且表單像預想中一樣消失了

當表單處於已提交狀態時,需要顯示一些別的東西。 在剛剛寫的<div>包裝下方,添加下列 HTML 語句:

<div [hidden]="!submitted">
  <div class="row">
    <div class="col-xs-3">Name</div>
    <div class="col-xs-9  pull-left">{{ model.name }}</div>
  </div>
  <button class="btn btn-primary" (click)="submitted=false">Edit</button>
</div>

當點Edit按鈕時,這個只讀塊消失了,可編輯的表單重新出現了

angular2-模板驅動表單