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 相关文章推荐
javascript 建设银行登陆键盘
Jun 10 Javascript
extJs 文本框后面加上说明文字+下拉列表选中值后触发事件
Nov 27 Javascript
Jquery数独游戏解析(一)-页面布局
Nov 05 Javascript
jQuery插件bxSlider实现响应式焦点图
Apr 12 Javascript
jquery实现键盘左右翻页特效
Apr 30 Javascript
javascript图片预加载实例分析
Jul 16 Javascript
JS上传图片预览插件制作(兼容到IE6)
Aug 07 Javascript
原生js实现jquery函数animate()动画效果的简单实例
Aug 21 Javascript
js中的面向对象入门
Mar 06 Javascript
浅谈Emergence.js 检测元素可见性的 js 插件
Nov 18 Javascript
为react组件库添加typescript类型提示的方法
Jun 15 Javascript
详解js创建对象的几种方式和对象方法
Mar 01 Javascript
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
自己前几天写的无限分类类
2007/02/14 PHP
PHP中error_reporting()函数的用法(修改PHP屏蔽错误)
2011/07/01 PHP
探讨php中header的用法详解
2013/06/07 PHP
详解PHP数组赋值方法
2015/11/07 PHP
PHP实现获取ip地址的5种方法,以及插入用户登录日志操作示例
2019/02/28 PHP
js jquery ajax的几种用法总结(及优缺点介绍)
2014/01/28 Javascript
单击某一段文字改写文本颜色
2014/06/06 Javascript
javascript创建cookie、读取cookie
2016/03/31 Javascript
Vue.js一个文件对应一个组件实践
2016/10/27 Javascript
用Angular实时获取本地Localstorage数据,实现一个模拟后台数据登入的效果
2016/11/09 Javascript
Javascript之面向对象--方法
2016/12/02 Javascript
浅谈JS获取元素的N种方法及其动静态讨论
2017/08/25 Javascript
JavaScript实现body内任意节点的自定义属性功能示例
2017/09/18 Javascript
vue基础之使用get、post、jsonp实现交互功能示例
2019/03/12 Javascript
Vue路由前后端设计总结
2019/08/06 Javascript
JS FormData对象使用方法实例详解
2020/02/12 Javascript
electron 如何将任意资源打包的方法步骤
2020/04/16 Javascript
初步探究Python程序的执行原理
2015/04/11 Python
Python获取系统默认字符编码的方法
2015/06/04 Python
开始着手第一个Django项目
2015/07/15 Python
Python标准库sched模块使用指南
2017/07/06 Python
python 找出list中最大或者最小几个数的索引方法
2018/10/30 Python
python实现爬山算法的思路详解
2019/04/09 Python
pandas删除行删除列增加行增加列的实现
2019/07/06 Python
python使用sklearn实现决策树的方法示例
2019/09/12 Python
解决Jupyter Notebook使用parser.parse_args出现错误问题
2020/04/20 Python
python 两种方法修改文件的创建时间、修改时间、访问时间
2020/09/26 Python
爱奇艺VIP会员:大剧抢先看
2018/07/11 全球购物
师范生教师实习自我鉴定
2013/09/27 职场文书
市场营销专业个人求职信范文
2013/12/14 职场文书
个人培训自我鉴定
2014/03/28 职场文书
产品生产计划书
2014/05/07 职场文书
二手车交易协议书标准版
2014/11/16 职场文书
2015年超市员工工作总结
2015/05/04 职场文书
创业计划书之便利店
2019/09/05 职场文书
idea以任意顺序debug多线程程序的具体用法
2021/08/30 Java/Android