AnjularJS 表單驗證(ng-form)

在HTML中,用戶通過inputselecttextarea等元素進行輸入,我們通常用表單來包裝和管理這些控件。客戶端表單驗證非常重要,可以及時地爲用戶提供表單驗證信息。但客戶端表單驗證只是爲了增強用戶體驗,服務器端驗證仍然是必要的。

AngularJS最大的特點便是數據綁定。利用Angular在客戶端腳本中構建MVC框架,Model和View之間可以實現雙向綁定。因此AngularJS的表單驗證可以做到實時的用戶反饋

事實上,正是因爲實時的用戶反饋這個神奇的特性,我們團隊在 http://tianmaying.com 中也繼續引入了AngularJS,儘管此時我們對單頁應用已經不感興趣。

一個簡單的表單

Angular是模塊化的,每個APP都是一個Angular Module。我們知道Module下可以包含這樣四種內容:

  • 控制器(controllers),用來完成頁面邏輯,不包含DOM操作、資源獲取。
  • 服務(services),用來提供資源訪問和獲取,控制資源的訪問,維護數據一致性。
  • 過濾器(filters),用來格式化數據顯示,很多第三方插件以提供filter爲主,例如angular-moment
  • 語義標籤(directives),增強的HTML標籤,DOM操作都應當抽象爲directive

Angular表單其實是Angular提供的Directive,它有一個別名叫ng-form。是這個Directive實例化了一個FormController來負責表單內的頁面邏輯(主要是表單驗證)。

<div ng-app>
  <ng-form name=someForm>
    <input name="username" type="text" ng-model="user.username" pattern="^\w{6,18}$">
    <div class="alert alert-danger" ng-show="someForm.username.$error.pattern">
      用戶名必須爲6-18個字母、數字或下劃線
    </div>
  </ng-form>
</div>

ng-model可以把input的值雙向地綁定到當前上下文的user.username變量。我們設置了用戶名的pattern爲6到18位。我們輸入用戶名時,.alert錯誤提示便會實時地顯示或者隱藏。

這裏我們指定了formname屬性,form Directive 實例化的FormController就會以someForm命名,並插入到當前$scope。所以在模板中才能夠訪問userForm變量。另外,Angular的Pattern使用Javascript正則表達式語法,這裏\w相當於[a-zA-Z_]

SELECT標籤

HTML中的select標籤是一個單選的下拉列表,Angular對select也提供了支持(事實上,是在ngModule裏面提供了一個叫select的Directive)。假如上下文中有這樣的對象:

$scope.selectValue = [{value: 0, label: 'Banana'}, {value: 1, label: 'Apple'}];
$socpe.selectedValue = 1;

在模板中這樣寫:

<select ng-model="selectedValue"
        ng-options="option.value as option.label for option in myOptions"></select>

這個<select>的便會有兩個選項:BananaApple,且默認選中Banana。當你選擇Apple時,$socpe.selectedValue會被賦值爲1option.value指定了<select><option>value,而option.label指定了<option>的內容。

事實上,因爲select下拉項的樣式不可通過CSS控制,select在追求視覺體驗的網站不常使用。Bootstrap的.dropdown就是一個更好的替代品。Angular也有類似的Dropdown插件。

表單嵌套

多數瀏覽器不允許form嵌套,如果你出於自身的需求(例如:在賬號表單中,頭像表單需要單獨提交)需要嵌套的表單,請使用ng-form標籤:

<ng-form name="outterForm">
  <ng-form name="innerForm" ng-repeat="file in doc.files">
    ...
    <button ng-disabled="innerForm.$invalid">Save Inner</button>
  </ng-form>
  <button ng-disabled="outterForm.$invalid || innerForm.$invalid">Save Outter</button>
</ng-form>

這裏的outterForm下有一個動態的innerForm列表,

  • innerForm下的元素$scope中是當前列表項的innerForm。因此Save Inner的狀態會根據正確地綁定到當前表單的狀態。
  • outterForm下的Save Outter則會同時綁定outterForminnerForm的狀態,當所有innerForm合法且outterForm合法時,按鈕被激活。

至於你自己的Directive希望通過屬性的方式來啓用還是通過標籤的方式來啓用,可以在你的Directive中設置restrict字段。

漸進呈現

在頁面載入時,由於Angular的控制器仍爲完成構造過程,表單會短暫地顯示爲原始的HTML,比如:

當然你能想到最直接的解決方案是給表單加一個隱藏的樣式,在載入後去掉它。然而Angular已經提供ngCloakDirective來完成這件事情,我們只需要在表單上加一個ng-cloak

<form ng-cloak>...</form>

ng-cloak可以直接加在body上,但在載入過程中,整個body都會隱藏。這與HTML的漸進呈現的原則是相悖的。建議在表單上單獨地應用ng-cloak

HTML屬於流式文檔,已載入的部分的呈現方式總是已知的。在帶寬小的情況下,HTML會逐步顯示已載入的部分。

轉載原創:http://harttle.com/2015/06/04/angular-form.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章