zoukankan      html  css  js  c++  java
  • (译) 在AngularJS中使用的表单验证功能

    验证功能是AngularJS里面最酷炫的功能之一,它可以让你写出一个具有良好用户体验的Web应用。

    在AngularJS中,有许多用于验证的指令。我们将先学习几个最流行的内置指令,然后再创建一个自定义验证规则的指令。

    <form name="form">
      <label name="email">Your email</label>
      <input type="email" name="email" ng-model="email" placeholder="Email Address" />
    </form>

    AngularJS可以让我们轻松的处理客户端验证。虽然我们不能仅靠客户端验证来保证我们Web应用的安全性,但他们提供了良好用户体验。

    我们首先必须确保form上标签有一个name属性,像上面的例子一样。

    我们可以进行一些基本的验证,例如最小长度,最大长度,等等,这些都是HTML5自带的属性验证功能。

    Tips:通常需要在form标签中加上novalidate属性,这样可以禁用浏览器自带的验证功能,从而使用AngularJS提供的。

    下面来看看我们可以在input中设置哪些验证:

    必填

    验证是否已输入文字,只需在标签上加上required

    <input type="text" required />

    最小长度

    验证至少输入{number}个字符,使用指令ng-minlength=“{number}”

    <input type="text" ng-minlength=5 />

    最大长度

    验证至多输入{number}个字符,使用指令ng-maxlength=“{number}”

    <input type="text" ng-maxlength=20 />

    正则匹配

    确保输入匹配一个正则表达式,使用指令ng-pattern="/PATTERN/":

    <input type="text" ng-pattern="/a-zA-Z/" />

    Email

    验证输入是一个Email,设置inputtype属性为email

    <input type="email" name="email" ng-model="user.email" />

    数字

    验证输入是一个数字,设置inputtype属性为number

    <input type="number" name="number" ng-model="user.age" />

    Url

    验证输入是一个URL,设置inputtype属性为url

    <input type="url" name="homepage" ng-model="user.facebook_url" />

    自定义验证

    AngularJS可以很容易的使用指令来添加自定义验证。例如,我们要验证我们的用户名是可用的(在数据库中不重复)。要做到这一点,我们将实现一个指令,它在输入字符变化时触发一个Ajax请求:

    var app = angular.module('validationExample', []);
    
    app.directive('ensureUnique', ['$http', function($http) {
      return {
        require: 'ngModel',
        link: function(scope, ele, attrs, c) {
          scope.$watch(attrs.ngModel, function() {
            $http({
              method: 'POST',
              url: '/api/check/' + attrs.ensureUnique,
              data: {'field': attrs.ensureUnique}
            }).success(function(data, status, headers, cfg) {
              c.$setValidity('unique', data.isUnique);
            }).error(function(data, status, headers, cfg) {
              c.$setValidity('unique', false);
            });
          });
        }
      }
    }]);

    验证表单状态

    AngularJS将DOM验证的结果保存在$scope对象中。这使我们能够实时做出一些处理。提供给我们的属性有:

    请注意,这是这个属性的格式:

    formName.inputFieldName.property

    未修改过的表单

    表示用户是否修改了表单。如果为ture,表示没有修改过:

    formName.inputFieldName.$pristine;

    修改的表单

    当且用户是否已经修改过表单:

    formName.inputFieldName.$dirty

    经过验证的表单

    表示否通过验证:

    formName.inputFieldName.$valid

    未通过验证的表单

    表示否通过验证。如果表单当前没有通过验证,他将为true

    formName.inputFieldName.$invalid

    最后两个属性在用于DOM元素的显示或隐藏时是特别有用的。当然,如果想要设置特定的class时,他们也是非常有用的。

    错误

    另一个有用的属性是AngularJS提供的$error对象。这个对象包含每一个无效的input验证的集合。为了访问这个属性,使用下面的语法:

    formName.inputfieldName.$error

    如果验证失败,则此属性将是true的(因为length>0)。

    控制验证时的样式

    当AngularJS处理的验证时,它将根据验证的状态增加一些特定的class属性。

    这些class是:

    .ng-pristine {}
    .ng-dirty {}
    .ng-valid {}
    .ng-invalid {}

    这些class对应着其对应的验证对象的结果。

    当一个字段是无效的,  .ng-invalid将被应用到这个字段上。我们可以通过css来设置这些class的样式:

    input.ng-invalid {
      border: 1px solid red;
    }
    input.ng-valid {
      border: 1px solid green;
    }

    全部放一起试试

    让我们编写一个注册表单。本申请表单将包括姓名,Email,以及用户名。

    让我们定义一个form表单:

    <form name="signup_form" novalidate ng-submit="signupForm()">
      <fieldset>
        <legend>Signup</legend>
    
        <button type="submit" class="button radius">Submit</button>
      </fieldset>
    </form>

    这个表单的名字是signup_form ,当我们点击提交时我们将调用signupForm()方法.

    现在,让我们添加用户的Name:

    <div class="row">
      <div>
        <label>Your name</label>
        <input type="text" 
            placeholder="Name" 
            name="name" 
            ng-model="signup.name" 
            ng-minlength=3 
            ng-maxlength=20 required />
      </div>
    </div>

     我们增加了一个名字为name的输入框,并且将对象绑定在$scope对象的signup.name对象上(通过ng-model)。

    我们还设置了几个验证。这些验证分别是:必须有一个长度为3或更多的名字。并且最大长度限制为20个字符。最后,名称应该是必填的。

    让我们用属性来控制显示还是隐藏错误信息。我们还将使用$dirty属性,以确保当用户没有输入字符前错误信息不会显示:

    <div class="row">
      <div>
        <label>Your name</label>
        <input type="text" 
            placeholder="Name" 
            name="name" 
            ng-model="signup.name" 
            ng-minlength=3 
            ng-maxlength=20 required />
       <div class="error" 
            ng-show="signup_form.name.$dirty && signup_form.name.$invalid">
        <small class="error" 
            ng-show="signup_form.name.$error.required">
            Your name is required.
        </small>
        <small class="error" 
                ng-show="signup_form.name.$error.minlength">
                Your name is required to be at least 3 characters
        </small>
        <small class="error" 
                ng-show="signup_form.name.$error.maxlength">
                Your name cannot be longer than 20 characters
        </small>
      </div>
      </div>
    </div>

    让我们接着看Email验证:

    <div class="row">          
      <div>
        <label>Your email</label>
        <input type="email" 
          placeholder="Email" 
          name="email" 
          ng-model="signup.email" 
          ng-minlength=3 ng-maxlength=20 required />
        <div class="error" 
             ng-show="signup_form.email.$dirty && signup_form.email.$invalid">
          <small class="error" 
                 ng-show="signup_form.email.$error.required">
                 Your email is required.
          </small>
          <small class="error" 
                 ng-show="signup_form.email.$error.minlength">
                  Your email is required to be at least 3 characters
          </small>
          <small class="error" 
                 ng-show="signup_form.email.$error.email">
                 That is not a valid email. Please input a valid email.
          </small>
          <small class="error" 
                 ng-show="signup_form.email.$error.maxlength">
                  Your email cannot be longer than 20 characters
          </small>
        </div>
      </div>
    </div>

    这一次,我们增加了Email字段。请注意,我们设置了input的type属性为email并且添加了$error.email错误信息。这是基于AngularJS的Email验证(使用了HTML5属性)。

    最后,让我们来看看在我们的最后一个验证,用户名:

    <div>
      <label>Username</label>
        <input  type="text" 
                placeholder="Desired username" 
                name="username" 
                ng-model="signup.username" 
                ng-minlength=3 
                ng-maxlength=20 
                ensure-unique="username" required />
      <div class="error" ng-show="signup_form.username.$dirty && signup_form.username.$invalid">
        <small class="error" ng-show="signup_form.username.$error.required">Please input a username</small>
        <small class="error" ng-show="signup_form.username.$error.minlength">Your username is required to be at least 3 characters</small>
        <small class="error" ng-show="signup_form.username.$error.maxlength">Your username cannot be longer than 20 characters</small>
        <small class="error" ng-show="signup_form.username.$error.unique">That username is taken, please try another</small>
      </div>
    </div>

    在我们的最后一个字段,我们使用之前编写的自定义验证指令:

    app.directive('ensureUnique', ['$http', function($http) {
      return {
        require: 'ngModel',
        link: function(scope, ele, attrs, c) {
          scope.$watch(attrs.ngModel, function() {
            $http({
              method: 'POST',
              url: '/api/check/' + attrs.ensureUnique,
              data: {'field': attrs.ensureUnique}
            }).success(function(data, status, headers, cfg) {
              c.$setValidity('unique', data.isUnique);
            }).error(function(data, status, headers, cfg) {
              c.$setValidity('unique', false);
            });
          });
        }
      }
    }]);

    当表单输入是有效的时,它将发送POST api/check/username请求到服务器来检查用户名是否可用。很明显,因为我们在这里只谈论前端代码,我们写后端代码,尽管很容易。

    更新: 

    根据评论,我加入了服务器超时检查。要查看完整的源代码,请点击here

    最后,我们加上提交按钮,根据验证是否有效使用ng-disabled来控制按钮的禁用和启用:

    <button type="submit" ng-disabled="signup_form.$invalid" class="button radius">Submit</button>

    正如我们上面所说的,表单是否有效的属性$invalid给我们提供了便利。

    更新 2: 

    虽然及时验证很棒,它可以立即提醒用户,但是当他们正在输入很长的能通过验证的文字时,他们将在输入中途看到错误提示。有更好的方式来处理验证:当用户点击提交时,或者当他们将光标移开输入框之后。让我们来看看这2种方式。

    点击提交后显示验证信息

    要在用户试图提交表单时显示的验证,你可以通过在scope中设置一个'submitted'值,并检查该值来控制显示错误。

    让我们来看看第一个例子,只有在点击提交表单时才显示错误。使用ng-show指令来控制显示,我们可以添加一个检查,看是否已点击提交按钮:

    <form name="signup_form" novalidate ng-submit="signupForm()">
      <fieldset>
        <legend>Signup</legend>
        <div class="row">
          <div>
            <label>Your name</label>
            <input type="text" 
                placeholder="Name" 
                name="name" 
                ng-model="signup.name" 
                ng-minlength=3 
                ng-maxlength=20 required />
           <div class="error" 
                ng-show="signup_form.name.$dirty && signup_form.name.$invalid && signup_form.submitted">
            <small class="error" 
                ng-show="signup_form.name.$error.required">
                Your name is required.
            </small>
            <small class="error" 
                    ng-show="signup_form.name.$error.minlength">
                    Your name is required to be at least 3 characters
            </small>
            <small class="error" 
                    ng-show="signup_form.name.$error.maxlength">
                    Your name cannot be longer than 20 characters
            </small>
          </div>
          </div>
        </div>
        <button type="submit" class="button radius">Submit</button>
      </fieldset>
    </form>

     现在,那个错误信息只将在signup_form.submittedtrue时才显示。我们可以这样实现signupForm方法:

    app.controller('signupController', ['$scope', function($scope) {
      $scope.submitted = false;
      $scope.signupForm = function() {
        if ($scope.signup_form.$valid) {
          // Submit as normal
        } else {
          $scope.signup_form.submitted = true;
        }
      }
    }]);

    现在,当用户尝试提交表单并且同时有一个无效的元素时,你可以捕获它,并告诉他们错误的原因。

    当时去焦点时验证错误

    如果你想保留错误验证的实时性,那么可以在用户离开该输入框时显示错误信息。要做到这一点,我们可以添加一个指令,将添加一个新的变量。

    我们使用ngFocus指令:

    app.directive('ngFocus', [function() {
      var FOCUS_CLASS = "ng-focused";
      return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
          ctrl.$focused = false;
          element.bind('focus', function(evt) {
            element.addClass(FOCUS_CLASS);
            scope.$apply(function() {ctrl.$focused = true;});
          }).bind('blur', function(evt) {
            element.removeClass(FOCUS_CLASS);
            scope.$apply(function() {ctrl.$focused = false;});
          });
        }
      }
    }]);

    要使用ngFocus,我们只需要简单加上这个指令到输入框元素上,像这样:

    <input ng-class="{error: signup_form.name.$dirty && signup_form.name.$invalid}" type="text" placeholder="Name" name="name" ng-model="signup.name" ng-minlength=3 ng-maxlength=20 required ng-focus />

    加上ngFocus指令后,将在输入框的blur和focus事件中注册相应操作,当焦点在该输入框时,它添加一个class(ng-focused),并且该输入框的$focused属性也将变为true。因此,你可以根据需求是否在焦点上来个性化设置显示错误消息。例如:

    <div class="error" ng-show="signup_form.name.$dirty && signup_form.name.$invalid && !signup_form.name.$focused">

    我希望这篇文章可以告诉你如何很酷炫的使用AngularJS来进行验证。

    原文:Form validation with AngularJS (en)

    注:原文有一些demo可供测试,若有需要请查看原文。

  • 相关阅读:
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 133 克隆图
  • 原文地址:https://www.cnblogs.com/woshinidezhu/p/Form-validation-with-AngularJS.html
Copyright © 2011-2022 走看看