表單控件(input, select, textarea )是用來獲取用戶輸入的。表單則是一組有聯系的表單控件的集合。
用戶能通過表單和表單控件提供驗證的服務,知道自己的輸入是否合法。這樣能讓用戶交互變得友好,因為用戶能通過反饋來修正自己的錯誤。不過,雖然客戶端的驗證能夠起到很大作用,但也很容易被繞過,所以不能完全依靠客戶端驗證。 要建立安全的應用,服務器端驗證還是必不可少的。
了解AngularJS雙向綁定的關鍵在於了解ngModel
指令。這個指令通過動態將model和view互相映射,來實現雙向綁定。
為了能美化表單和表單元素,ngModel指令會自動為元素添加以下css類:
一個表單就是一個FormController
的實例,表單實例可以通過name屬性選擇性地公開到作用域中。同樣的,一個表單控件也是一個NgModelController
的實例,表單控件也能同樣的被公開到作用域中。這意味視圖能通過綁定的基本功能獲取表單或者表單控件的狀態。
舉個例子:
<!doctype html> <html ng-app> <head> <script src="http://code.angularjs.org/angular-1.0.2.min.js"></script> <script> function Controller($scope) { $scope.master= {}; $scope.update = function(user) { $scope.master= angular.copy(user); }; $scope.reset = function() { $scope.user = angular.copy($scope.master); }; $scope.isUnchanged = function(user) { return angular.equals(user, $scope.master); }; $scope.reset(); } </script> </head> <body> <div ng-controller="Controller"> <form name="form" class="css-form" novalidate> //novalidate是用來屏蔽浏覽器本身的驗證功能的。 Name: <input type="text" ng-model="user.name" name="uName" required /><br /> //required,此輸入框必須有內容 E-mail: <input type="email" ng-model="user.email" name="uEmail" required/><br /> <div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">Invalid: //此div,如果form表中的name為uEmail的input元素中的內容違法或者是髒數據,那麼就顯示出來。 <span ng-show="form.uEmail.$error.required">Tell us your email.</span> //如果錯誤信息是由required引起的,就顯示此span <span ng-show="form.uEmail.$error.email">This is not a valid email.</span> //如果錯誤信息是由裡面的內容不合法引起的,就顯示此span </div> Gender: <input type="radio" ng-model="user.gender" value="male" />male <input type="radio" ng-model="user.gender" value="female" />female<br /> <input type="checkbox" ng-model="user.agree" name="userAgree" required /> I agree: <input ng-show="user.agree" type="text" ng-model="user.agreeSign" required /><br /> <div ng-show="!user.agree || !user.agreeSign">Please agree and sign.</div> <button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button> <button ng-click="update(user)" ng-disabled="form.$invalid || isUnchanged(user)">SAVE</button> //如果整個form表單沒有通過驗證或者form表單中的內容沒有發生改變,此按鈕就不可點擊 </form> </div> </body> </html>
AngularJS實現了大部分常見的html5表單輸入元素(text, number, url, email, radio, checkbox),也實現了很多用於驗證的指令(required, pattern, minlength, maxlength, min, max)。
如果想要定義你自己的驗證器的話,可以通過在你自己的指令中添加一個驗證函數給ngModel的控制器來實現。要想獲得控制器的引用,需要在指令中指定依賴,驗證函數可以寫在兩個地方。
模型到視圖的更新中- 只要綁定的模型改變了,NgModelController#$formatters數組中的函數就會被輪流調用,所以每一個函數都有機會對數據進行格式化,當然你也可以通過NgModelController#$setValidity來改變表單的驗證狀態。
視圖到模型的更新中- 相同的,只要用戶與表單交互了,NgModelController#$setViewValue就會被調用。 這次是NgModelController#$parsers數組中的函數會被依次調用,每個函數都有機會來改變值或者通過NgModelController#$setValidity來改變表單的驗證狀態。下面的例子,使用的是這個。
舉個例子:
<!doctype html> <html ng-app="form-example1"> <head> <script src="http://code.angularjs.org/angular-1.0.2.min.js"></script> <script> var app = angular.module('form-example1', []); var INTEGER_REGEXP = /^\-?\d+$/; //或者以"-"(負)開頭,或者沒有負號,後面都是正整數,包括0 app.directive('integer', function() { return { require: 'ngModel', //依賴nogModel指令 link: function(scope, elm, attrs, ctrl) { ctrl.$parsers.unshift(function(viewValue) { //ctrl可以調用ngModel指令中controller函數中定義的方法 if (INTEGER_REGEXP.test(viewValue)) { ctrl.$setValidity('integer', true); return viewValue; } else { ctrl.$setValidity('integer', false); return undefined; } }); } }; }); var FLOAT_REGEXP = /^\-?\d+((\.|\,)\d+)?$/; //可以是正負,可以是整數,也可以是浮點數,浮點數可以用"."分開,也可以用","分開。 app.directive('smartFloat', function() { return { require: 'ngModel', link: function(scope, elm, attrs, ctrl) { ctrl.$parsers.unshift(function(viewValue) { if (FLOAT_REGEXP.test(viewValue)) { ctrl.$setValidity('float', true); return parseFloat(viewValue.replace(',', '.')); } else { ctrl.$setValidity('float', false); return undefined; } }); } }; }); </script> </head> <body> <div ng-controller="Controller"> <form name="form" class="css-form" novalidate> <div> Size (integer 0 - 10): <input type="number" ng-model="size" name="size" min="0" max="10" integer />{{size}}<br /> //integer,自定義指令 <span ng-show="form.size.$error.integer">This is not valid integer!</span> <span ng-show="form.size.$error.min || form.size.$error.max">The value must be in range 0 to 10!</span> </div> <div> Length (float): <input type="text" ng-model="length" name="length" smart-float />{{length}}<br /> //smart-float,自定義指令
<span ng-show="form.length.$error.float">This is not a valid float number!</span> </div> </form> </div> </body> </html>
上面的例子中,我們創建了兩個指令。
第一個指令是要驗證輸入的是否是整數。例如,1.23就不符合驗證的值,因為它包含了分數部分。
第二個指令是要驗證輸入的是否是“智能浮點(smart-float)”。它能把"1.2"或者"1,2"都轉化為合法的浮點數"1.2"。注意,這裡我們不能使用input元素的type="number",因為支持HTML5的浏覽器不允許用戶輸入像"1,2"這樣的非法值。
AngularJS已經實現了所有基本的HTML表單控件(input,select,textarea),對於大部分情況應該已經夠了。但是,你還是可以通過寫指令來實現你自己的表單控件。
要和ngModel指令協同工作實現自定義控件,並且實現雙向綁定的話,需要:
下面的例子演示了如何添加一個“內容可編輯”的數據雙向綁定的元素。
<!doctype html> <html ng-app="form-example2"> <head> <script src="http://code.angularjs.org/angular-1.0.2.min.js"></script> <script> angular.module('form-example2', []).directive('contenteditable', function() { //自定義指令contenteditable return { require: 'ngModel', link: function(scope, elm, attrs, ctrl) { // view -> model elm.bind('blur', function() { //給元素div綁定blur事件 scope.$apply(function() { ctrl.$setViewValue(elm.html()); //當輸入結束後,焦點離開div元素時,就更新model }); }); // model -> view ctrl.$render = function(value) { elm.html(value); //更新視圖view }; // load init value from DOM ctrl.$setViewValue(elm.html()); } }; }); </script> </head> <body> <div contentEditable="true" ng-model="content" title="Click to edit">Some</div> <pre>model = {{content}}</pre> <style type="text/css"> div[contentEditable] { cursor: pointer; background-color: #D0D0D0; } </style> </body> </html>
AngularJS權威教程 清晰PDF版 http://www.linuxidc.com/Linux/2015-01/111429.htm
希望你喜歡,並分享我的工作~帶你走近AngularJS系列:
如何在 AngularJS 中對控制器進行單元測試 http://www.linuxidc.com/Linux/2013-12/94166.htm
在 AngularJS 應用中通過 JSON 文件來設置狀態 http://www.linuxidc.com/Linux/2014-07/104083.htm
AngularJS 之 Factory vs Service vs Provider http://www.linuxidc.com/Linux/2014-05/101475.htm
AngularJS —— 使用 ngResource、RESTful APIs 和 Spring MVC 框架提交數據 http://www.linuxidc.com/Linux/2014-07/104402.htm
AngularJS 的詳細介紹:請點這裡
AngularJS 的下載地址:請點這裡