AngularJS实现表单手动验证和表单自动验证


Posted in Javascript onDecember 09, 2015

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 >
 <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:
● 安装: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 >
 <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 >
 <!--<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 >
 <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']对应。

本文的全部内容就为大家介绍到这里,希望对大家学习AngularJS实现表单验证有所帮助。

Javascript 相关文章推荐
jQuery 研究心得 取得属性的值
Nov 30 Javascript
JS去除字符串的空格增强版(可以去除中间的空格)
Aug 26 Javascript
通用javascript脚本函数库 方便开发
Oct 13 Javascript
一个简单的js渐显(fadeIn)渐隐(fadeOut)类
Jun 19 Javascript
深入document.write()与HTML4.01的非成对标签的详解
May 08 Javascript
JS延时器提示框的应用实例代码解析
Apr 27 Javascript
vue实现列表的添加点击
Dec 29 Javascript
Bootstrap modal 多弹窗之叠加显示不出弹窗问题的解决方案
Feb 23 Javascript
浅谈微信小程序flex布局基础
Sep 10 Javascript
解决JavaScript中0.1+0.2不等于0.3问题
Oct 23 Javascript
一些手写JavaScript常用的函数汇总
Apr 16 Javascript
vue-element-admin项目导入和导出的实现
May 21 Vue.js
js实现微信分享代码
Oct 11 #Javascript
JavaScript观察者模式(经典)
Dec 09 #Javascript
常用的Javascript设计模式小结
Dec 09 #Javascript
JS实现字符串转日期并比较大小实例分析
Dec 09 #Javascript
jQuery实现批量判断表单中文本框非空的方法(2种方法)
Dec 09 #Javascript
详解JavaScript基本类型和引用类型
Dec 09 #Javascript
jQuery中serializeArray()与serialize()的区别实例分析
Dec 09 #Javascript
You might like
php5新改动之短标记启用方法
2008/09/11 PHP
PHP 编程安全性小结
2010/01/08 PHP
PHP的可变变量名的使用方法分享
2012/02/05 PHP
php页面消耗内存过大的处理办法
2013/03/18 PHP
PHP内核探索:变量存储与类型使用说明
2014/01/30 PHP
php之static静态属性与静态方法实例分析
2015/07/30 PHP
thinkphp 手机号和用户名同时登录
2017/01/20 PHP
PHP实现的支付宝支付功能示例
2019/03/26 PHP
PHP实现爬虫爬取图片代码实例
2021/03/03 PHP
浅谈JavaScript字符串与数组
2015/06/03 Javascript
使用JQuery实现的分页插件分享
2015/11/05 Javascript
jquery对象访问是什么及使用方法介绍
2016/05/03 Javascript
Bootstrap中glyphicons-halflings-regular.woff字体报404错notfound的解决方法
2017/01/19 Javascript
JavaScript下拉菜单功能实例代码
2017/03/01 Javascript
JS实现复制功能
2017/03/01 Javascript
jQuery实现上下滚动公告栏详细代码
2018/11/21 jQuery
[00:18]天涯墨客三技能展示
2018/08/25 DOTA
[01:05:59]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.22
2019/09/05 DOTA
[47:45]DOTA2-DPC中国联赛 正赛 Phoenix vs Dragon BO3 第一场 2月26日
2021/03/11 DOTA
python二叉树遍历的实现方法
2013/11/21 Python
使用python统计文件行数示例分享
2014/02/21 Python
web.py在模板中输出美元符号的方法
2014/08/26 Python
Python实现保证只能运行一个脚本实例
2015/06/24 Python
详解Python编程中对Monkey Patch猴子补丁开发方式的运用
2016/05/27 Python
python去除空格和换行符的实现方法(推荐)
2017/01/04 Python
Python随机生成均匀分布在三角形内或者任意多边形内的点
2017/12/14 Python
Python学习笔记之列表推导式实例分析
2019/08/13 Python
Python生成个性签名图片获取GUI过程解析
2019/12/16 Python
澳大利亚时尚前卫设计师珠宝在线:Amber Sceats
2017/10/04 全球购物
上班玩游戏检讨书
2014/02/07 职场文书
情人节寄语大全
2014/04/11 职场文书
2014年六一儿童节演讲稿
2014/05/23 职场文书
安全生产先进个人总结
2015/02/15 职场文书
写给媳妇的检讨书
2015/05/06 职场文书
MySQL单表千万级数据处理的思路分享
2021/06/05 MySQL
golang中的struct操作
2021/11/11 Golang