Angular提供了一些常用的html5输入控件的验证实现:(text, number, url, email, radio, checkbox), 以及一些用于验证的指令 (required, pattern, minlength, maxlength, min, max)。这里只介绍模式匹配ng-pattern
指令。
使用ng-pattern="/PATTERN/"
来确保输入能够匹配指定的正则表达式:
注意:要使用HTML 表单属性 novalidate 禁用浏览器默认的验证。
属性 | 描述 | 对应的CSS样式 |
---|---|---|
$dirty | 表单有填写记录 | .ng-dirty {} |
$valid | 字段内容合法的 | .ng-valid {} |
$invalid | 字段内容是非法的 | .ng-invalid {} |
$pristine | 表单没有填写记录 | .ng-pristine {} |
$error | 当前表单的所有验证内容,以及它们是否合法的信息。如果验证失败,这个属性的值为true;如果值为false,说明输入字段的值通过了验证。 |
你可以使用formName.inputFieldName.property
来验证某个输入框的内容,或通过formName.property
来验证整个表单所有输入框的内容。
一个表单是一个 FormController
的实例。
一个拥有 api/ng.directive:ngModel
指令的输入控件,包含一个NgModelController
实例。
ngModel.NgModelController为ng-model指令提供了API。该控制器包含数据绑定,验证,CSS更新服务,和值的格式化和解析。它很明确的不包含任何逻辑处理,DOM渲染或者监听事件。这种与DOM相关的逻辑应该由其他使用NgModelController进行数据绑定指令提供。
$render();
当视图需要更新时调用。
$isEmpty(value);
当我们需要判断input的值是否为空时可执行。例如, input的值是否存在,则需要的指令执行此函数。默认的$isEmpty函数检查值是否是“undefined”、“”、null或者NaN。
Value:检查的引用。
$setValidity(validationErrorKey,isValid);
改变有效性的状态,并通知表单当前控制器的有效性发生变化。(如果验证器已经被标记为无效,则不通知表单。)
在需要验证的时候这种方法被调用—即分析器或格式化功能。
validationErrorKey:验证器的名称。validationErrorKey将会被分配给$error[validationErrorKey ] =isValid,这样就可以进行数据绑定了。
isValid:当前状态是否是valid(true)或者invalid(false)。
$setPristine();
设置控制器初始化状态。
$setViewValue(value);
更新页面的值。
当页面上的值发生变化时,这个方法被调用。
value:页面上的值。
属性:
$viewValue
页面上实际的字符串值。
$modelValue
模型中控制器绑定的的该值。$modelValue
由数据模型持有。$modelValue
和$viewValue
可能是不同的,取决于$parser
流水线是否对其进行了操作。
$parsers
被执行的功能数组,作为一个控制器从DOM读取值的管道。每一个函数被调用去传递值到下一个,最后返回值用于填充模型。用于净化/转换或者验证值。为了验证,解析器应该使用$setvalidity()更新有效状态,并返回未定义的无效值。
$formatters
被执行功能的数组,作为一个控制器从DOM读取值的管道。每一个函数被调用去传递值到下一个,最后返回值用于填充模型。用于的格式化/转换在控制器和验证中显示的值。
$viewChangeListeners
当页面上值变化时所执行的函数的数组。它没有参数被执行,它的返回值被忽略。这可以用来代替对模型值额外的监听。
$error
带有所有错误的hash对象。
$pristine
用户还没有与控制器交互,则为true。
$dirty
用户已经与控制器交互,则为true。
$valid
如果没错误,则为true。
$invalid
控制器上至少有一个错误,则为true。
表单的验证在两个时机触发:
NgModelController#$formatters
数组中的方法会被管道式调用(即:一个接一个的调用方法),这样一来,所有的方法都有机会对值来进行格式化并改变表单和控件的有效性状态,这将通过调用NgModelController#$setValidity
来实现。NgModelController#$setViewValue
. 这又反过来管式调用了所有在NgModelController#$parsers
数组中的方法,这样一来,所有的方法都有机会对值来进行转换并改变表单和控件的有效性状态,通过NgModelController#$setValidity
来实现。使用$parsers
数组是实现自定义验证的途径之一。例如,假设我们想要确保输入值在某两个数值之间,可以在$parsers
数组中入栈一个新的函数,这个函数会在验证链中被调用。
每个$parser
返回的值都会被传入下一个$parser
中。当不希望数据模型发生更新时返回undefined。
angular.module('myApp')
.directive('oneToTen', function() {
return {
require: '?ngModel',
link: function(scope, ele, attrs, ngModel) {
if (!ngModel) return;
ngModel.$parsers.unshift(function(viewValue) {
var i = parseInt(viewValue);
if (i >= 0 && i < 10) {
ngModel.$setValidity('oneToTen', true);
return viewValue;
} else {
ngModel.$setValidity('oneToTen', false);
return undefined;
}
});
}
};
});
当绑定的ngModel值发生了变化,并经过$parsers
数组中解析器的处理后,这个值会被传递给$formatters
流水线。同$parsers
数组可以修改表单的合法性状态类似,$formatters
中的函数也可以修改并格式化这些值。
比起单纯的验证目的,这些函数更常用来处理视图中的可视变化。例如,假设我们要对某个值进行格式化。通过$formatters
数组可以在这个值上执行过滤器:
angular.module('myApp')
.directive('oneToTen', ['$filter', function($filter) {
return {
require: '?ngModel',
link: function(scope, ele, attrs, ngModel) {
if (!ngModel) return;
ngModel.$formatters.unshift(function(v) {
return $filter('number')(v);
});
}
};
}]);
为了能让自定义控件能够与’ngModel’正常工作,达到双向绑定的效果,它需要:
$render
方法,它负责在数据传递给方法NgModelController#$formatters
之后渲染数据。$setViewValue
方法,在任何用户与控件交互后,模型需要更新的时候调用。这通常在一个DOM事件监听器里完成。ngModel.$setViewValue(value)
函数会更新控制器上本地的$viewValue
,然后将值传递给每一个$parser
函数(包括验证器)。
当值被解析,且$parser
流水线中所有的函数都调用完成后,值会被赋给$modelValue
属性,并且传递给指令中ng-model
属性提供的表达式。
最后,所有步骤都完成后,$viewChangeListeners
中所有的监听器都会被调用。
注意,单独调用$setViewValue()
不会唤起一个新的digest循环,因此如果想更新指令,需要在设置$viewValue
后手动触发digest。
$setViewValue()
方法适合于在自定义指令中监听自定义事件(比如使用具有回调函数的jQuery插件),我们会希望在回调时设置$viewValue
并执行digest循环。
angular.module('form-example2', []).directive('contenteditable', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
// 视图 -> 模型
elm.on('blur', function() {
scope.$apply(function() {
ctrl.$setViewValue(elm.html());
});
});
// 模型 -> 视图
ctrl.$render = function() {
elm.html(ctrl.$viewValue);
};
// 从DOM中初始化数据
ctrl.$setViewValue(elm.html());
}
};
});
注意,这个指令没有隔离作用域。如果给这个指令设置隔离作用域,将导致内部ngModel无法更新外部ngModel的对应值:AngularJS会在本地作用域以外查询值。
在验证表单填入数据时,如果数据有错或无效会显示提示信息,在用angular写表单时,提示信息可以用ng-show
在触发情况是显示,为了减少重复标记,可以利用ngMessages指令。
angular-messages是angular的一个模块,可以作为应用程序依赖模块引入:
angular.module("MyApp",["ngMessages"]);
<form name="signup_form" novalidate ng-submit="signupForm()" ng-controller="signupController">
<label>Your namelabel>
<input type="text"
placeholder="Name"
name="name"
ng-model="signup.name"
ng-minlength=3
ng-maxlength=20 required/>
<div class="error" ng-messages="signup_form.name.$error">
<div ng-message="required">Make sure you enter your namediv>
<div ng-message="minlength">Your name must be least 3 charactersdiv>
<div ng-message="maxlength">Your name cannot be longer than 20 charactersdiv>
div>
<button type="submit">Submitbutton>
form>
这样如果填入表单数据有误,就会出现提示,一次只会出现一个消息,而且出现的顺序就是代码中的顺序,如果需要同时显示所有错误,就需要在ng-messages
指令旁加上ng-messages-mutiple
。
或者很多时候视图中多个地方需要调用相同的提示消息,这时可以将消息保存到模板中,如下:
方法1
<!--In template/error.html-->
<div ng-message="required">This field is requireddiv>
<div ng-message="minlength">The field must be at least 3 charactersdiv>
<div ng-message="maxlength">The field cannot be longer than 20 charactersdiv>
方法2
<script type="text/ng-template" id="my-custom-messages">
"required">This field is required</div>
This field is too shortdiv>
script>
然后在视图中使用ng-messages-include
引入此模板地址或id:
<div class="error" ng-messages="signup_form.name.$error" ng-messages-include="template/error.html">
div>
<div class="error" ng-messages="signup_form.name.$error" ng-messages-include="my-custom-messages">
div>