AngularJS自带了对表单或控件的输入数据进行验证的功能,对于Html5的基础控件均有内建的验证器,以下列举了所有支持的验证类型:

  • email
  • max
  • maxlength
  • min
  • minlength
  • number
  • pattern
  • required
  • url
  • date
  • datetimelocal
  • time
  • week
  • month

AngularJS会在元素上自动添加如下样式:

  • ng-valid: 验证通过
  • ng-invalid: 验证失败
  • ng-valid-[key]: 由$setValidity添加的所有验证通过的值
  • ng-invalid-[key]: 由$setValidity添加的所有验证失败的值
  • ng-pristine: 控件为初始状态
  • ng-dirty: 控件输入值已变更
  • ng-touched: 控件已失去焦点
  • ng-untouched: 控件未失去焦点
  • ng-pending: 任何为满足$asyncValidators的情况

示例1:

 <!DOCTYPE >
<html>
<head>
<style type="text/css">
.ng-invalid.ng-dirty {
border-color: #FA787E;
} .ng-valid.ng-dirty {
border-color: #78FA89;
} .ng-pristine.ng-pristine {
border-color: #ffd800;
}
</style> <script src="/Scripts/angular.js"></script>
<script type="text/javascript">
(function () {
var app = angular.module('validationTest', []); app.controller('myController', ['$scope', function ($scope) {
$scope.students = []; $scope.addStudent = function (stu) {
$scope.students.push(stu);
$scope.stu = {};
};
}]);
})();
</script>
</head>
<body ng-app="validationTest" ng-controller="myController">
<form name="myForm" ng-submit="myForm.$valid && addStudent(stu)" novalidate>
Name:
<input name="name" ng-model="stu.name" required />
<span ng-hide="myForm.name.$pristine || myForm.name.$valid" ng-show="myForm.name.$invalid">Name is required.</span>
<br />
Age:
<input name="age" ng-model="stu.age" type="number" max="200" min="1" required />
<span ng-hide="myForm.age.$pristine || myForm.age.$valid" ng-show="myForm.age.$invalid">Age is required and should between 1-200.</span>
<br />
Sex:
<select name="sex" ng-model="stu.sex" required>
<option value="0">Male</option>
<option value="1">Female</option>
</select>
<span ng-hide="myForm.sex.$pristine || myForm.sex.$valid" ng-show="myForm.sex.$invalid">Sex is required.</span>
<br />
Email:
<input name="email" ng-model="stu.email" type="email" />
<span ng-hide="myForm.email.$pristine || myForm.email.$valid" ng-show="myForm.email.$invalid">Email is not correct.</span>
<br />
Blog:
<input name="blog" ng-model="stu.blog" type="url" />
<span ng-hide="myForm.blog.$pristine || myForm.blog.$valid" ng-show="myForm.blog.$invalid">Blog is not correct.</span>
<br />
Birthday:
<input name="birthday" ng-model="stu.birthday" type="datetime-local" />
<span ng-hide="myForm.birthday.$pristine || myForm.birthday.$valid" ng-show="myForm.birthday.$invalid">Birthday is not correct.</span> <div>myForm.$valid is {{myForm.$valid}}</div>
<div>myForm.$invalid is {{myForm.$invalid}}</div>
<div>myForm.$pristine is {{myForm.$pristine}}</div>
<div>myForm.$dirty is {{myForm.$dirty}}</div>
<div>myForm.$submitted is {{myForm.$submitted}}</div> <div>myForm.age.$error is {{myForm.age.$error}}</div> <input type="submit" value="Submit" />
</form>
<hr />
<div ng-repeat="stu in students">
<span>Name:{{ stu.name }}</span>
<span>Age:{{ stu.age }}</span>
<span>Sex:{{ stu.sex == 0 ? "Male" : "Female" }}</span>
<span>Email:{{ stu.email }}</span>
<span>Blog:{{ stu.blog }}</span>
<span>Birthday:{{ stu.birthday }}</span>
<hr />
</div>
</body>
</html>

示例1中,首先对form添加novalidate属性来禁用form的浏览器默认验证行为:

<form name="myForm" ng-submit="myForm.$valid && addStudent(stu)" novalidate>

对必填的控件添加required属性:

<input name="name" ng-model="stu.name" required />

本例有2种验证结果展示方式:

1. 控件边框颜色变化:

本文开头已说过,AngularJS会在验证控件后自动添加内建的样式名称,因此,我们只需对这些预定义的样式名称添加实际的样式代码即可:

 .ng-invalid.ng-dirty {
border-color: #FA787E;
} .ng-valid.ng-dirty {
border-color: #78FA89;
} .ng-pristine.ng-pristine {
border-color: #ffd800;
}

2. 文字显示验证失败原因(以name控件为例):

<span ng-hide="myForm.name.$pristine || myForm.name.$valid" ng-show="myForm.name.$invalid">Name is required.</span>

ng-hide:当name为初始化状态或者通过验证的状态,无需显示错误信息提示;

ng-show:当name控件验证失败时,展示错误提示信息。

AngularJS还提供了一些内建的状态值,方便我们直接使用:

  • $dirty:内容已变更
  • $pristine:初始化状态
  • $valid:验证通过
  • $invalid:验证失败
  • $submitted:已提交
  • $error:所有验证失败的hash对象
  • $$success:所有验证通过的hash对象
  • $pending:所有pending(异步验证)的hash对象

form中添加ng-submit属性,并且当myForm.$valid(即myForm中包含的所有验证均通过时,该值才为true)提交表单并调用addStudent方法:

<form name="myForm" ng-submit="myForm.$valid && addStudent(stu)" novalidate>

这样,当在页面上填写完有效的信息后,我们就可以将学生对象添加到Controller的students中,并由于双向绑定的特性,最终将提交的信息同步展示到页面上。

自定义验证器

你可能也猜到了,AngularJS也为我们准备好了自定义验证的方式。AngularJS实际上是通过自定义Directive,并在link中将验证方法添加到指定控件的$validators中, 在$validators中定义的对象必须有modelValue和viewValue两个参数,AngluarJS会在底层调用$setValidity来验证它。

我们看一个简单的例子,自定义验证Directive:myInteger(my-integer),输入值必须是以“1”开头,并为3位数字。

示例2:

 <!DOCTYPE >
<html>
<head>
<script src="/Scripts/angular.js"></script>
<script type="text/javascript">
(function () {
var app = angular.module('customValidationTest', []); var INTEGER_REGEXP = /^\-?1\d{2}$/;
app.directive('myInteger', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$validators.myInteger = function (modelValue, viewValue) {
if (ctrl.$isEmpty(modelValue)) {
return true;
} if (INTEGER_REGEXP.test(viewValue)) {
return true;
} return false;
};
}
};
}); })();
</script>
</head>
<body ng-app="customValidationTest">
<form name="myForm" ng-submit="myForm.$valid" novalidate>
My integer:<input name="myInteger" ng-model="custInt" my-integer required />
<span ng-hide="myForm.myInteger.$pristine || myForm.myInteger.$valid" ng-show="myForm.myInteger.$invalid">My integer is required and should be the value 1xx.</span>
</form>
</body>
</html>

修改AngularJS的内建验证器方法

当然如果你需要重写AngularJS内建的验证也是可以的。

示例3(官方Demo):

 <!DOCTYPE >
<html>
<head>
<script src="/Scripts/angular.js"></script>
<script type="text/javascript">
(function () {
var app = angular.module('modifyBuildinValidatorTest', []); app.directive('overwriteEmail', function () {
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i;
return {
require: 'ngModel',
restrict: '',
link: function (scope, elm, attrs, ctrl) {
// 仅当存在ngModel且存在email这个验证器的时候才替换
if (ctrl && ctrl.$validators.email) { // 这里将重写AngularJS默认的email验证器
ctrl.$validators.email = function (modelValue) {
return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
};
}
}
};
});
})();
</script>
</head>
<body ng-app="modifyBuildinValidatorTest">
<form name="form" class="css-form" novalidate>
<div>
Overwritten Email:
<input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
<span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
Model: {{myEmail}}
</div>
</form>
</body>
</html>

在创建Directive:overwriteEmail并定义它的行为时,首先判断是否当前控件存在,且控件上已定义了email这个验证器,若存在则改写其验证。

本例中,改写后的email验证,将使以@example.com为后缀的email地址才能通过验证。

本篇讲述了AngularJS的控件验证方式以及自定义验证器,学会了使用验证器,我们就可以控制页面输入数据的合法性了,这样,我们的页面逻辑就更加完善了。

参考资料

AngularJS官方文档:https://docs.angularjs.org/guide/forms

CodeSchool快速入门视频:http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro

AngularJS入门之数据验证的更多相关文章

  1. AngularJS快速入门指南14:数据验证

    thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table ...

  2. AngularJs 入门系列-2 表单验证

    对于日常的开发来说,最常见的开发场景就是通过表单编辑数据,这里涉及的问题就是验证问题. angularjs 内置已经支持了常见的验证方式,可以轻松实现表单验证. 1. 绑定 为了方便,我们在 $sco ...

  3. ASP.NET MVC 入门8、ModelState与数据验证

    原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/08/1305962.html ViewData有一个ModelState的属性,这是一个类型 ...

  4. AngularJS(10)-数据验证

    AngularJS 表单和控件可以提供验证功能,并对用户输入的非法数据进行警告.客户端的验证不能确保用户输入数据的安全,所以服务端的数据验证也是必须的. <!DOCTYPE html> & ...

  5. [转]ASP.NET MVC 入门8、ModelState与数据验证

    ViewData有一个ModelState的属性,这是一个类型为ModelStateDictionary的ModelState类型的字典集合.在进行数据验证的时候这个属性是比较有用的.在使用Html. ...

  6. WPF MVVM从入门到精通8:数据验证

    原文:WPF MVVM从入门到精通8:数据验证 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 WPF M ...

  7. Struts2入门(四)——数据输入验证

    一.前言 1.1.什么是输入验证?为什么需要输入验证? 在上一篇文章中,我们学习了数据类型转换,我们提到了表示层数据处理的两个方法,也提到了用户输入数据需要进行类型转换才能得到我们想要的数据,那么,我 ...

  8. ASP.NET MVC3 入门指南之数据验证[源码RAR下载]

    http://www.cnblogs.com/BingoLee/archive/2011/12/23/2298822.html 前言: 无论你编写什么样的网页程序,都需要对用户的数据进行验证,以确数据 ...

  9. 【转载】图灵AngularJS入门教程

    摘自图灵的AngularJS入门教程:http://www.ituring.com.cn/article/13471 感觉非常不错,所以推荐到首页一下! (一)Hello World! 开始学习Ang ...

随机推荐

  1. 2018.10.17 NOIP模拟 发电机(概率dp)

    传送门 考试空间开大了爆零不然只有30分爆栈? 话说这题真的坑1e7没法写dfsdfsdfs 其实很好推式子. 考虑每个点安一个发动机的概率,推一波式子做个等比数列求和什么的可以证明出来是严格的1si ...

  2. 2018.07.08 hdu5316 Magician(线段树)

    Magician Problem Description Fantasy magicians usually gain their ability through one of three usual ...

  3. Docker swarm结合Openresty部署rabbitmq集群

    Docker swarm结合Openresty部署rabbitmq集群 大家好,年底了,年味儿越来越浓了.2019年的寒冬被定义为未来10年中最好的一年,对于这一说法悲观的人和乐观的人的理解是不一样的 ...

  4. arduino空调遥控器

    参考:http://www.arduino.cn/thread-3487-1-1.html http://www.arduino.cn/thread-3618-1-1.html 注意1:有金属外壳的一 ...

  5. IntelliJ IDEA 2017版 spring-boot修改端口号配置把端口号改为8081

    1.修改端口号主要是通过配置文件修改.如图: 完整版配置 ######################################################## ###server 配置信息 ...

  6. day11(多线程,唤醒机制,生产消费者模式,多线程的生命周期)

    A:进程: 进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. B:线程: 线程是进程中的一个执行单元,负责当前进程中程序的执 ...

  7. <context:component-scan>自动扫描

    主要讲解自动扫描的<context:component-scan>中的2个子标签的使用方法 在Spring MVC中的配置中一般会遇到这两个标签,作为<context:compone ...

  8. 【python】基础入门

    1.正则表达式 import re sql="aaa$1bbbbccccc$2sdfsd gps_install_note_id =$3;" regexp=r'\$\d+' # 编 ...

  9. c# AOP编程:Context与方法拦截

    之前做AgentBooking时候,遇到两个问题比较棘手,一个是异常的传递与捕获:如何可以合理地在层层代码调用中统一传递并统一捕获异常.因为如果有一个做法,可以地方统一处理异常,可以使代码减少很多tr ...

  10. linux系统编程之管道(三):命令管道(FIFO)

    一,匿名管道PIPE局限性 管道的主要局限性正体现在它的特点上: 只支持单向数据流: 只能用于具有亲缘关系的进程之间: 没有名字: 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配 ...