歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> AngularJS開發指南6:AngularJS表單詳解

AngularJS開發指南6:AngularJS表單詳解

日期:2017/3/1 9:34:01   编辑:Linux編程

表單控件(input, select, textarea )是用來獲取用戶輸入的。表單則是一組有聯系的表單控件的集合。

用戶能通過表單和表單控件提供驗證的服務,知道自己的輸入是否合法。這樣能讓用戶交互變得友好,因為用戶能通過反饋來修正自己的錯誤。不過,雖然客戶端的驗證能夠起到很大作用,但也很容易被繞過,所以不能完全依靠客戶端驗證。 要建立安全的應用,服務器端驗證還是必不可少的。

了解AngularJS雙向綁定的關鍵在於了解ngModel指令。這個指令通過動態將model和view互相映射,來實現雙向綁定。

為了能美化表單和表單元素,ngModel指令會自動為元素添加以下css類:

  • ng-valid
  • ng-invalid
  • ng-pristine
  • ng-dirty

一個表單就是一個FormController的實例,表單實例可以通過name屬性選擇性地公開到作用域中。同樣的,一個表單控件也是一個NgModelController的實例,表單控件也能同樣的被公開到作用域中。這意味視圖能通過綁定的基本功能獲取表單或者表單控件的狀態。

  • 只有當表單發生改變時,重置按鈕才會被顯示出來。
  • 只有當表單有改變並且改變的值都是合法的,保存按鈕才會被顯示出來。
  • 能自定義user.email和user.agree的錯誤信息。

舉個例子:

<!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指令協同工作實現自定義控件,並且實現雙向綁定的話,需要:

  • 實現render方法。這個方法負責在數據模型變化時,把變化的值傳遞給NgModelController#$formatters後,用來在view上渲染新的數據。
  • 在用戶與控件交互並且模型需要被更新時,調用$setViewValue方法。這通常是在DOM的監聽事件中完成的。

下面的例子演示了如何添加一個“內容可編輯”的數據雙向綁定的元素。

<!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系列

  1. 帶你走近AngularJS - 基本功能介紹 http://www.linuxidc.com/Linux/2014-05/102140.htm
  2. 帶你走近AngularJS - 體驗指令實例 http://www.linuxidc.com/Linux/2014-05/102141.htm
  3. 帶你走近AngularJS - 創建自定義指令 http://www.linuxidc.com/Linux/2014-05/102142.htm

如何在 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 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved