網頁中用戶於服務端交互數據的表單控件有input、select、textarea,而表單是將爲了達到一個目的(登陸、註冊等)各類控件整合到一塊兒的一個集合。
表單和其中的表單控件提供了驗證服務,可讓用戶在提交(通常在點擊類型爲submit的按鈕時提交)表單前意識到本身有非法(不符合要求,如下都將稱爲非法)的輸入。這種驗證方式(客戶端驗證)提供了比單獨的服務端驗證更好的用戶體驗,由於用戶在輸入後獲得實時的反饋,修正輸入的信息。
可是雖說客戶端驗證提供了更好的用戶體驗,可是服務端驗證也是不可或缺的,由於客戶端驗證並不可靠並且很容易被繞過。爲了編寫一個可靠的應用程序,服務端驗證是不可或缺的。css
用於理解雙向數據綁定的關鍵指令是ngModel(指令在視圖中使用時須要將大寫字母裝換爲-x,例如ng-model),ngModel(ngBind)指令提供了模型與視圖之間的雙向數據綁定的方法。另外,ngModel爲其餘指令擴展其行爲提供了API(應用程序編程接口)。html
<body ng-controller="myCtrl"> <form name="basicForm" novalidate> <div class="form-group"> <label for="name">姓名:</label> <input type="text" id="name" ng-model="user.name" class="form-control"> </div> <div class="form-group"> <label for="email">郵箱:</label> <input type="email" id="email" ng-model="user.email" class="form-control"> </div> <div class="form-group"> <label for="gender">性別:</label> <label class="radio-inline"> <input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="male" ng-model="user.gender"> 男 </label> <label class="radio-inline"> <input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="female" ng-model="user.gender"> 女 </label> </div> <div class="text-center"> <button class="btn btn-success" type="submit" ng-click="save()">保存</button> <button class="btn btn-danger" ng-click="reset()">重置</button> </div> </form> <pre> user:{{ user | json }} </pre> <pre> User:{{ User | json }} </pre> <script> angular.module('basicForm',[]) .controller('myCtrl',['$scope', function ($scope) { $scope.User = {}; $scope.save = function () { $scope.User = angular.copy($scope.user); } $scope.reset = function () { $scope.user = angular.copy($scope.User) } }]) </script> </body>
這裏有幾個須要注意的點:編程
novalidate是用來禁用瀏覽器自帶的驗證。json
ngModel的值不會被設置,直到經過了控件的驗證,好比說type=email必須爲xxx@xxx的形式,能夠仔細看下方user中email字段的變化。瀏覽器
建議不要使用type=reset的按鈕,會將輸入框清空,但不會重置數據模型中的值,緣由未知。異步
在不一樣的驗證狀態下,ngModel爲控件和表單提供了一些css類(須要在樣式表中聲明):ui
ng-valid:數據模型合法spa
ng-invalid:數據模型不合法code
ng-valid-[key]:每個經過$setValidity添加的合法鍵orm
ng-invalid-[key]:每個經過$setValidity添加的不合法的鍵
ng-pristine:尚未與用戶交互(輸入過)的控件
ng-dirty:與用戶交互過的控件
ng-touched:失去過焦點的控件(鼠標點上去得到,點其餘地方失去)
ng-untouched:沒有失去過焦點的控件
ng-pending:任何沒有結束(與服務端交互)的異步驗證
這裏簡單的演示ng-invalid和ng-touched
html:
<form name="basicForm" novalidate> <div class="form-group"> <label for="name">姓名:</label> <input type="text" id="name" ng-model="user.name" class="form-control" required> </div> <div class="form-group"> <label for="email">郵箱:</label> <input type="email" id="email" ng-model="user.email" class="form-control"> </div> <div class="form-group"> <label for="gender">性別:</label> <label class="radio-inline"> <input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="male" ng-model="user.gender"> 男 </label> <label class="radio-inline"> <input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="female" ng-model="user.gender"> 女 </label> </div> <div class="text-center"> <button class="btn btn-success" type="submit" ng-click="save()">保存</button> </div> </form>
css:
.ng-invalid.form-control { border-color: #E96666; box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(233, 102, 102, 0.6) } .ng-touched.form-control { border-color: #66E985; box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 233, 160, 0.6) }
第一個輸入框由於是必須的,因此是非法的狀態,因此angular會給這個控件添加ng-invalid樣式,在輸入後變爲合法,該樣式去除,在失去焦點後ng-touched樣式添加
表單是FormController的一個實例,咱們能夠用表單的name屬性將表單暴露到做用域中。
類似的,一個有數據綁定(有ngModel)的表單控件也是NgModelController的實例,也能夠經過表單實例的屬性(控件的name)暴露到做用域中。
咱們能夠經過這個特性擴展咱們上一個例子:
在用戶與表單控件交互後再展現錯誤信息
在用戶點擊提交以後再展現錯誤信息
<form name="register_form" novalidate> <div class="form-group"> <label for="name">姓名:</label> <input type="text" ng-model="user.name" id="name" class="form-control" name="name" required> </div> <div class="alert alert-danger" ng-show="register_form.$error.required && (register_form.$submitted || register_form.name.$touched)"> <strong>注意!</strong> 姓名不能爲空 </div> <div class="form-group"> <label for="email">email:</label> <input type="email" ng-model="user.email" id="email" class="form-control" name="email"> </div> <div class="form-group"> <label for="male">性別:</label> <label class="radio-inline"> <label class="radio-inline"> <input type="radio" name="inlineRadioOptions" id="male" value="male" ng-model="user.gender"> 男 </label> <label class="radio-inline"> <input type="radio" name="inlineRadioOptions" id="female" value="female" ng-model="user.gender"> 女 </label> </label> </div> <button type="submit" class="btn btn-block btn-primary">提交</button> </form>
注意一下,$submitted表示是否點擊過提交(type=submit)按鈕,開發遇到問題的時候,你們也能夠把$error打印出來看下,表單和表單中的控件都有$error對象,這裏我都打印出來了
在默認狀況下,對數據的任何改變都會促發模板的更新和表單驗證。咱們可使用ngModelOptions指令去重寫這個行爲,使只有在特定的條件下才觸發。
好比說
ng-model-options="{ updateOn: 'blur' }"
會只在表單控件失去焦點時觸發,咱們也能夠設置多個事件來觸發,只要使用空格隔開便可
ng-model-options="{ updateOn: 'mousedown blur' }"
若是想把原有的保存,只是想加一個觸發條件的話,能夠加上default在列表中
ng-model-options="{ updateOn: 'default blur' }"
一個完整點的例子:
html:
<form class="row"> <div class="col-sm-6"> <h3>促發條件: blur</h3> <input type="text" class="form-control" ng-model="user.name" ng-model-options="{ updateOn: 'blur' }"> {{ user.name }} </div> <div class="col-sm-6"> <h3>正常</h3> <input type="text" class="form-control" ng-model="user.phone"> {{ user.phone }} </div> </form>
咱們能夠經過ngModelOptions的debounce 關鍵字來使數據綁定延遲,這個延遲對解析器,驗證和表單的屬性($dirty,$pristine等)都會生效。
寫法也很簡單
ng-model-options="{ debounce: 500 }"
ngModelOptions是能夠繼承的,因此若是有多個控件都須要這個效果,能夠在他們的父元素上添加這個指令,除非子元素重寫這個屬性。
<div class="col-sm-6" ng-model-options="{ updateOn: 'default blur', debounce: { default: 1000, blur: 0 } }"> <h3>促發條件: blur</h3> <input type="text" class="form-control" ng-model="user.name"> {{ user.name }} </div>
至於自定義表單驗證,我會另寫一篇。剛開博客沒多久,但願你們有任何問題或者意見都在下方提出,或者加我qq 651882883。