Angular使用總結 --- 模版驅動表單


  表單的重要性就不多說了,Angular支持表單的雙向數據綁定,校驗,狀態管理等,總結下。

獲取用戶輸入

 1 <div class="container-fluid login-page">
 2   <h1>Angular表單</h1>
 3   <form class="login-area">
 4     <div class="form-group">
 5         <input class="form-control" type="text" name="name" id="login-name" placeholder="請輸入登錄帳號">
 6     </div>
 7     <div class="form-group">
 8       <input class="form-control"type="password" name="pwd" id="login-pwd" placeholder="請輸入登錄密碼">
 9     </div>
10     <div class="form-group">
11       <button type="submit" class="btn btn-block btn-success">登錄</button>
12     </div>
13   </form>
14 </div>

  假如有以上簡單表單,先不論優劣,有哪些方式可以獲取到表單數據呢? 先看兩種簡單粗暴的

  1)事件$event的方式

  在監聽事件的時候,將整個事件載荷 $event 傳遞到事件處理函數,它會攜帶觸發元素的各種信息。這里監聽form元素的submit事件,將整個form的信息傳給處理函數,並打印出來

<form class="login-area"  (submit)="testInput($event)">
testInput ( _input: any) {
    console.dir(_input);
}

  觸發submit后,查看結果。非常眼熟,就是傳統方式中的event嘛,后面就不用多說了,target即為form元素,再定位到input子元素,分別獲取value即可。

  為了獲取input的Value,我們傳遞了非常多的無用信息,處理函數根本就不關心元素的位置,屬性等等,它只需要value值。所以這種方式不可取

  2) 模版引用變量

  Angular中可以用 模版引用變量(#var)來引用DOM元素/Angular組件/指令。通常模版引用變量就是代表聲明的那個元素,當然也可以修改指向,可以代表Angular指令(比如后續用到的ngForm指令和ngModel指令)。

// 模版引用變量代表Form元素
<form class="login-area" #test  (submit)="testInput(test)">

// 模版引用變量代表ngForm指令
<form class="login-area" #test="ngForm"(submit)="testInput(test)">

  從下圖可以看到不同,第一個和$event.target一樣,是DOM元素;第二個是ngForm指令,可以跟蹤每個控件的值和狀態(是否輸入過?是否校驗通過?等等),后續會詳細說

  所以當我們直接用模版引用變量引用input元素時,就可以直接在模版中傳遞input元素的value,而不需要傳遞整個元素信息。這種方式也不好,必須要通過事件觸發才可以傳遞

  <form class="login-area" (submit)="testInput(test.value)">
    <div class="form-group">
        <input class="form-control" #test  type="text" name="name" id="login-name" placeholder="請輸入登錄帳號">
    </div>

  注意:模版引用變量的作用域是整個模版,所以在同一個模版中,不能有同名的模版引用變量

  這兩種獲取表單數據的方式只是了解下,因為Angular提供了兩種更好的構建表單的方式---模版驅動表單和模型驅動表單

模版驅動表單

  顧名思義,是使用 HTML模版 + 表單專業指令 來構建表單。使用模版驅動表單,記得要先在應用模塊中import FormsModule 。 說明以下幾點:

  1、模版驅動表單使用 [(ngModel)] 語法進行雙向數據綁定,非常簡單就可以把表單數據綁定到模型中。注意在表單中使用[ngModel]時,必須要定義name屬性,因為Angular在處理表單時,會創建一些FormControl,用來跟蹤單個表單控件的值和狀態,而表單控件name屬性就是鍵值,所以必須要指定name屬性。(這應該算是指出了獲取表單數據的兩種科學的方式:[ngModel]語法綁定 和 通過formControl的Api獲取)

  2、使用 ngForm指令,來監聽整個表單的有效性(valid屬性)。Angular會自動為form表單自動創建並添加ngForm指令,直接使用即可

  3、使用ngModel指令,來監聽單個表單控件的狀態,還會使用特定的Angular css來更新控件樣式 , 我們可以通過這些class來控制不同狀態時,表單控件的展示

  

  4、表單驗證可以使用 HTML原生的表單驗證屬性(required , pattern , max , min 等等) ,驗證出錯時,3中提到的errors屬性就會有對應的錯誤項;

     還可以自定義驗證器,因為模版驅動表單不直接訪問FormControl實例,所以需要把自定義的驗證器用指令包裝。

  通過以下栗子來展示模版驅動表單簡單使用

        <!-- 模版引用變量指向ngForm指令 -->
  <form class="login-area" #testform="ngForm" (submit)="testInput()">
    <div class="form-group">
        <!-- ngModel綁定數據 -->
        <!-- required 和 pattern 指定校驗規則 -->
        <!-- 模版引用變量指向ngModel指令 -->
        <input class="form-control" type="text" name="name" id="login-name" placeholder="請輸入登錄帳號"
               [(ngModel)] = "user.name"   
               required
               pattern="[0-9A-z]+"
               #nameinput = "ngModel"
               >
    </div>
        <!-- 通過表單控件的狀態控制是否展示錯誤說明及展示何種錯誤說明 -->
    <div class="form-group" *ngIf="nameinput.touched&&nameinput.invalid">
        <span class="error-info" *ngIf="nameinput.errors?.required">用戶名不能為空!</span>
        <span class="error-info" *ngIf="nameinput.errors?.pattern">用戶名只能包含英文或數字!</span>
    </div>
    <div class="form-group">
      <input class="form-control" type="password" name="pwd" id="login-pwd" placeholder="請輸入登錄密碼"
             [(ngModel)] = "user.pwd"
             required
             #pwdinput = "ngModel">
    </div>
    <div class="form-group" *ngIf="pwdinput.touched&&pwdinput.invalid">
      <span class="error-info" *ngIf="pwdinput.errors?.required">密碼不能為空!</span>
    </div>
    <div class="form-group">
      <!-- 通過表單的狀態控制按鈕是否可用 -->
      <button type="submit" class="btn btn-block btn-success" [disabled]="testform.invalid">登錄</button>
    </div>
  </form>

  通過Angular css 自動添加的class來控制表單樣式   

input.ng-invalid.ng-touched{
        border: 2px solid red;
 }

  查看下效果,表單校驗、樣式反饋、按鈕狀態管理、數據獲取都很方便。

  至於如何自定義驗證器會在下一篇介紹;隨筆中有不足的歡迎大家指正···


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM