zoukankan      html  css  js  c++  java
  • AngularJS表单验证,手动验证或自动验证

    AngularJS的表单验证大致有两种,一种是手动验证,一种是自动验证。


    手动验证


    所谓手动验证是通过AngularJS表单的属性来验证。而成为AngularJS表单必须满足两个条件:1、给form元素加上novalidate="novalidate";2、给form元素加上name="theForm",如下:

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp1">
    <head>
      <meta charset="UTF-8">
      <title></title>
      <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css"/>
      <link rel="stylesheet" href="../css/main.css"/>
    </head>
    <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a href="/" class="navbar-brand">Form Submitting</a>
        </div>
      </div>
    </nav>
    
    <div class="container main-content" ng-controller="myCtrl1">
      <!--novalidate让表单不要使用html验证-->
      <!--theForm变成scope的一个字段-->
      <form ng-submit="onSubmit(theForm.$valid)" novalidate="novalidate" name="theForm">
        <div class="form-group">
          <label for="name">Name</label>
          <input type="text" class="form-control" id="name" ng-model="formModel.name"/>
        </div>
    
        <div class="form-group" ng-class="{
          'has-error': !theForm.email.$valid && (!theForm.$pristine || theForm.$submitted),
          'has-success': theForm.email.$valid && (!theForm.$pristine || theForm.$submitted)
          }">
          <label for="email">Email</label>
          <input type="email" class="form-control" id="email" ng-model="formModel.email" required="required" name="email"/>
          <p class="help-block" ng-show="theForm.email.$error.required && (!theForm.$pristine || theForm.$submitted)">必填</p>
          <p class="help-block" ng-show="theForm.email.$error.email && (!theForm.$pristine || theForm.$submitted)">email格式不正确</p>
        </div>
    
        <div class="form-group">
          <label for="username">Username</label>
          <input type="text" class="form-control" id="username" ng-model="formModel.username"/>
        </div>
    
        <div class="form-group">
          <label for="age">Age</label>
          <input type="number" class="form-control" id="age" ng-model="formModel.age"/>
        </div>
    
        <div class="form-group">
          <label for="sex">Sex</label>
          <select name="sex" id="sex" class="form-control" ng-model="formModel.sex">
            <option value="">Please choose</option>
            <option value="male">Mail</option>
            <option value="femail">Femail</option>
          </select>
        </div>
    
        <div class="form-group">
          <label for="password">Password</label>
          <input type="text" class="form-control" id="password" ng-model="formModel.password"/>
        </div>
    
        <div class="form-group">
          <button class="btn btn-primary" type="submit">Register</button>
        </div>
    
          <pre>
            {{theForm | json}}
          </pre>
      </form>
    </div>
    <script src="../node_modules/angular/angular.min.js"></script>
    <script src="second.js"></script>
    </body>
    </html>


    以上,

    ● 给form加上novalidate="novalidate"意味着表单将不再使用HTML5验证特性
    ● 给form加上name="theForm"意味着表单的名称是theForm。如何使用theForm,比如我们验证表单是否被修改过theForm.$submitted
    ● 通过ng-submit提交表单
    ● formModel是$scope中的一个属性
    ● 对表单的Email进行了手动验证,使用了AngularJS表单的众多属性,比如theForm.email.$valid,theForm.$pristine,theForm.$submitted, theForm.email.$error.required,theForm.email.$error.email
    ● 通过<pre>{{theForm | json}}</pre>把AngularJS表单的所有属性都打印出来

    {
      "$error": {
        "required": [
          {
            "$validators": {},
            "$asyncValidators": {},
            "$parsers": [],
            "$formatters": [
              null
            ],
            "$viewChangeListeners": [],
            "$untouched": true,
            "$touched": false,
            "$pristine": true,
            "$dirty": false,
            "$valid": false,
            "$invalid": true,
            "$error": {
              "required": true
            },
            "$name": "email",
            "$options": null
          }
        ]
      },
      "$name": "theForm",
      "$dirty": false,
      "$pristine": true,
      "$valid": false,
      "$invalid": true,
      "$submitted": false,
      "email": {
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [],
        "$formatters": [
          null
        ],
        "$viewChangeListeners": [],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": false,
        "$invalid": true,
        "$error": {
          "required": true
        },
        "$name": "email",
        "$options": null
      },
      "sex": {
        "$validators": {},
        "$asyncValidators": {},
        "$parsers": [],
        "$formatters": [],
        "$viewChangeListeners": [],
        "$untouched": true,
        "$touched": false,
        "$pristine": true,
        "$dirty": false,
        "$valid": true,
        "$invalid": false,
        "$error": {},
        "$name": "sex",
        "$options": null
      }
    }

    以上,凡是有name属性的input都被显示在上面。

    在second.js文件中定义了module,controller以及提交表单的方法。

    var myApp1 = angular.module('myApp1',[]);
    
    myApp1.controller('myCtrl1', function($scope, $http){
        $scope.formModel = {};
    
        $scope.onSubmit = function(){
            $http.post('someurl',$scope.formModel)
                .success(function(data){
                    console.log(':)');
                })
                .error(function(data){
                    console.log(':(');
                });
    
            console.log($scope.formModel);
        };
    });

    以上的表单验证方式好处是可控性强,但相对繁琐。

    自动验证



    AngularJS的另外一种表单验证方式是自动验证,即通过directive来实现,除了AngularJS自带的directive,还需要用到angular-auto-validate这个第三方module。


    有关angular-auto-validate:

    ● 网址:https://github.com/jonsamwell/angular-auto-validate
    ● 安装:npm i angular-auto-validate
    ● 引用:<script src="../node_modules/angular-auto-validate/dist/jcs-auto-validate.min.js"></script>
    ● module依赖:var myApp = angular.module("app", ["jcs-autoValidate"]);


    为了实现错误信息本地化,还需要angular-localize这个第三方module:

    ● 安装:npm install angular-localize --save
    ● module依赖:var myApp = angular.module("app", ["localize"]);
    ● 引用:

    <script src="../node_modules/angular-sanitize/angular-sanitize.min.js"></script>
    <script src="../node_modules/angular-localize/angular-localize.min.js"></script>


    此外,当点击提交表单按钮,需要禁用按钮并显示一种等待效果,需要用到angular-ladda这个第三方module:

    ● 安装:bower install angular-ladda --save
    ● module依赖:var myApp = angular.module("app", ["angular-ladda"]);
    ● 引用:
    <link rel="stylesheet" href="../bower_components/ladda/dist/ladda-themeless.min.css"/>

    <script src="../bower_components/ladda/dist/spin.min.js"></script>
    <script src="../bower_components/ladda/dist/ladda.min.js"></script>
    <script src="../bower_components/angular-ladda/dist/angular-ladda.min.js"></script>

    页面如下:

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp1">
    <head>
      <meta charset="gb2312">
      <title></title>
      <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css"/>
      <link rel="stylesheet" href="../bower_components/ladda/dist/ladda-themeless.min.css"/>
      <link rel="stylesheet" href="../css/main.css"/>
    </head>
    <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a href="/" class="navbar-brand">Form Validating Auto</a>
        </div>
      </div>
    </nav>
    
    <div class="container main-content" ng-controller="myCtrl1">
      <!--novalidate让表单不要使用html验证-->
      <!--theForm变成scope的一个字段-->
      <form ng-submit="onSubmit()" novalidate="novalidate">
        <div class="form-group">
          <label for="name" class="control-label">Name</label>
          <input type="text" class="form-control" id="name" ng-model="formModel.name"  required="required"/>
        </div>
    
        <div class="form-group">
          <label for="email" class="control-label">Email</label>
          <input type="email" class="form-control" id="email" ng-model="formModel.email" required="required"/>
    
        </div>
    
        <div class="form-group">
          <label for="username" class="control-label">Username</label>
          <input type="text"
                 class="form-control"
                 id="username"
                 ng-model="formModel.username"
                 required="required"
                 ng-pattern="/^[A-Za-z0-9_]{1,32}$/"
                 ng-minlength="7"
                 ng-pattern-err-type="badUsername"
            />
        </div>
    
        <div class="form-group">
          <label for="age" class="control-label">Age</label>
          <input type="number"
                 class="form-control"
                 id="age"
                 ng-model="formModel.age"
                 required="required"
                 min="18"
                 max="65"
                 ng-min-err-type="tooYoung"
                 ng-max-err-type="tooOld"
            />
        </div>
    
        <div class="form-group">
          <label for="sex" class="control-label">Sex</label>
          <select name="sex" id="sex" class="form-control" ng-model="formModel.sex"  required="required">
            <option value="">Please choose</option>
            <option value="male">Mail</option>
            <option value="femail">Femail</option>
          </select>
        </div>
    
        <div class="form-group">
          <label for="password" class="control-label">Password</label>
          <input type="text" class="form-control" id="password" ng-model="formModel.password"  required="required" ng-minlength="6"/>
        </div>
    
        <div class="form-group">
          <!--<button class="btn btn-primary" ng-click="onSubmit()">Register</button>-->
          <button class="btn btn-primary"
                  ladda = "submitting"
                  data-style="expand-right"
                  type="submit">
            <span ng-show="submitting">正在注册...</span>
            <span ng-show="!submitting">注册</span>
          </button>
        </div>
    
          <pre>
            {{formModel | json}}
          </pre>
      </form>
    </div>
    <script src="../node_modules/angular/angular.min.js"></script>
    
    <script src="form_validation_auto.js"></script>
    <script src="../node_modules/angular-auto-validate/dist/jcs-auto-validate.min.js"></script>
    <script src="../node_modules/angular-sanitize/angular-sanitize.min.js"></script>
    <script src="../node_modules/angular-localize/angular-localize.min.js"></script>
    
    <script src="../bower_components/ladda/dist/spin.min.js"></script>
    <script src="../bower_components/ladda/dist/ladda.min.js"></script>
    <script src="../bower_components/angular-ladda/dist/angular-ladda.min.js"></script>
    
    </body>
    </html>

    以上,先看提交按钮:

    <div class="form-group">
      <!--<button class="btn btn-primary" ng-click="onSubmit()">Register</button>-->
      <button class="btn btn-primary"
              ladda = "submitting"
              data-style="expand-right"
              type="submit">
        <span ng-show="submitting">正在注册...</span>
        <span ng-show="!submitting">注册</span>
      </button>
    </div>

    ● ladda属性值为bool值,true表示显示动态等待效果,false不显示动态等待效果,这里的submitting是scope中的一个属性
    ● data-style="expand-right"表示在按钮的右侧显示动态等待效果

    再拿表单中的Age字段来说:

    <div class="form-group">
      <label for="age" class="control-label">Age</label>
      <input type="number"
             class="form-control"
             id="age"
             ng-model="formModel.age"
             required="required"
             min="18"
             max="65"
             ng-min-err-type="tooYoung"
             ng-max-err-type="tooOld"
        />
    </div>

    其中,min, max为AgularJS的directive,而ng-min-err-type是angular-auto-validate的directive。这里遵循的惯例是ng-AngularJS表单验证的directive名称-err-type,而tooYoung和tooOld的作用是什么,又是在哪里用上了呢?


    是在module层面用上了,定义在了form_validation_auto.js文件中。

    var myApp1 = angular.module('myApp1',['jcs-autoValidate','localize','angular-ladda']);
    
    myApp1.run(function(defaultErrorMessageResolver){
        defaultErrorMessageResolver.getErrorMessages().then(function(errorMessages){
            errorMessages['tooYoung'] = '年龄必须小于{0}';
            errorMessages['tooOld'] = '年龄不能大于{0}';
            errorMessages['badUsername'] = '用户名只能包含数字、字母或下划线';
        });
    });
    
    myApp1.controller('myCtrl1', function($scope, $http){
        $scope.formModel = {};
        $scope.submitting = false;
    
        $scope.onSubmit = function(){
    
            $scope.submitting = true;
            console.log('已提交');
            console.log($scope.formModel);
    
            $http.post('url',$scope.formModel)
                .success(function(data){
                    console.log(':)');
                    $scope.submitting = false;
                })
                .error(function(data){
                    console.log(':(');
                    $scope.submitting = false;
                });
        };
    });


    以上,在run方法中使用angular-auto-validate的defaultErrorMessageResolver服务,对错误信息进行为了自定义。页面上的tooYoung和tooOld和这里的errorMessages['tooYoung']和errorMessages['badUsername']对应。

  • 相关阅读:
    poj 3068 Bridge Across Islands
    XidianOJ 1086 Flappy v8
    XidianOJ 1036 分配宝藏
    XidianOJ 1090 爬树的V8
    XidianOJ 1088 AK后的V8
    XidianOJ 1062 Black King Bar
    XidianOJ 1091 看Dota视频的V8
    XidianOJ 1098 突击数论前的xry111
    XidianOJ 1019 自然数的秘密
    XidianOJ 1109 Too Naive
  • 原文地址:https://www.cnblogs.com/darrenji/p/5021667.html
Copyright © 2011-2022 走看看