Angular表单验证

在使用 AngularJS 进行开发的时候,表单填写是一个很常见的需求,而表单验证又是比较让人头疼的部分,本文对此做一个总结。

在 Angular 的视图中使用的 form 已经不是 HTML 中的普通 form 了,而是一个被 Angular 封装过的指令。它可以完成普通 form 无法实现的功能,比如 form 嵌套,而且自带强大的验证功能。

Angular 在对表单进行校验的时候会使用 ngModelController 上的属性,如果不设置 ng-model,则 Angular 无法知道 form.$invalid 这个值是否为真。后面在自定义验证有对它的介绍。

本文在对表单的验证时使用了 ng-messages,在文章最后也有对它的介绍。

本文涉及到的源码在 这里,实现效果在 这里

原生表单验证

在 form 层面,可以使用 ng-disabled 来控制提交按钮的状态,在 form 表单项全部验证通过前不可点击,下面介绍一下通用的表单项验证选项。

input 验证选项

AngularJS 的 input 标签 自带的验证选项有以下这些。

<input
  ng-model=""
  [name=""]
  [required=""]
  [ng-required=""]
  [ng-minlength=""]
  [ng-maxlength=""]
  [ng-pattern=""]
  [ng-change=""]>
...
</input>

a. 必填

<input type="text" name="myName" ng-model="username" required />

使用 ng-required 可以根据后面表达式的值设置是否 required

在不满足 requiredform.myName.$error{required: true}

b. 长度

<input type="text" name="myName" ng-model="username" ng-minlength="2" ng-maxlength="10" />

在不满足 ng-minlength/ng-maxlengthform.myName.$error{minlength: true, maxlength: true}

直接使用 minlength/maxlength 也有相同效果,而且 maxlength 可以设置最多输入 x 个字符,超过之后无法再输入。

c. 模式匹配

<input type="text" name="myDesc" ng-model="desc" ng-pattern="/^[a-zA-Z]{1,20}$/" />

在不满足 ng-patternform.myName.$error{pattern: true}

d. 其他

AngularJS 对特定格式也进行了校验。比如将 type 设置为 urlemail 等,在没有特殊验证要求的情况下,可以直接使用这些自带的校验,或者通过自定义指令修改 Angular 内建验证器。不同 type 有不同的验证选项,具体参考 AngularJS API 文档

CSS Classes

Angular 会根据表单状态自动给表单和表单项添加以下几组样式:

  • ng-valid 验证通过,与之相对的是 ng-invalid
  • ng-valid-[key] 通过自定义验证器添加的验证通过的值,与之相对的是 ng-invalid-[key]
  • ng-pristine 未交互状态,与之相对的是 ng-dirty
  • ng-touched 未访问状态,与之相对的是 ng-untouched
  • ng-pending 满足 $asyncValidators 的情况

这些在 ngModelController 的属性中都有对应值。

根据这些 class,可以为不同状态设置不同的样式,比如这样:

input.ng-valid.ng-dirty {
    border-color: #78FA89;
}

input.ng-invalid.ng-dirty {
    border-color: #FA787E;
}

自定义验证

AngularJS 指令入门 一文中,提到过通过 require 属性和 controller 参数,可以实现指令之间的交互。那么,在自定义指令中使用 require: ‘ngModel‘ 就可以使用 ngModel 指令的 controller 属性的实例了。

ngModelController

ngModel 提供了数据绑定、验证、CSS更新、数据格式化和编译等操作。下面简单介绍一下 ngModelController 常用的属性和方法。

核心属性

  1. $viewValue 视图里的值
  2. $modelValue 数据模型里值

input 事件触发的时候,$viewValue 会同步到 $modelValue 。默认情况下,这个是一旦 input 中的内容有改变就触发。AngularJS 1.3 引入了 ng-model-options,可以让这个同步延迟到 blur 或者延迟一定的时间之后。

<input type="text" name="username" ng-model="username" ng-model-options="{updateOn:‘blur‘}">
<input type="text" name="username" ng-model="username" ng-model-options="{ debounce: 500 }">

$viewValue 的值同步到 $modelValue 时,会经过 $parsers$validators$asyncValidators 三个核心管道(后两个是 AngularJS 1.3 以后新加的)进行处理,通过后才更新到 $modelValue 上(如果验证器管道没通过,不会更新)。

核心管道

  1. $parsers 改变视图值的格式,并更新的到模型($viewValue -> $modelValue),与之相对的是 $formatters,刚好反过来。
  2. $validators 用来添加同步验证器
  3. $asyncValidators 用来添加异步验证器

常用属性

  1. $error 没有通过的验证器名称及对应的错误信息
  2. $valid 表单项是否都通过验证,都通过时为 true,与之相对的是 $invalid
  3. $touched 表单项是否被访问过,如果获得过焦点,在失去时该值为 true,与之相对的是 $untouched
  4. $dirty 表示用户是否和表单项交互过(比如输入一些东西),只要有任何改变,该值为 true,与之相对的是 $pristine

常用方法

  1. $render 定义视图具体的渲染方式
  2. $setViewValue 设置视图值(需要手动触发一个 $digest),使用场景是在自定义指令中监听自定义事件(比如使用具有回调的 jQuery 插件)

自定义同步验证 & 异步验证

ngModelController 中讲到,AngularJS 1.3 提供了验证器管道,同步验证只需要加到 $validators 上即可。

比如,有这样一个常见的需求,对一个必填的名称表单项,要求只能输入中英文,最小长度为2位字符,那么可以这样实现。

指令:

app.directive(‘nameCheck‘, nameCheck);

nameCheck.$inject = [‘$http‘, ‘$q‘];

function nameCheck($http, $q){
    var NAME_REG = /^[a-zA-Z\u4e00-\u9fa5]+$/;
    return {
        restrict: ‘A‘,
        require: ‘ngModel‘,
        link:function($scope,element,attrs,ctrl){
            // 同步验证
            ctrl.$validators.char = function(modelValue, viewValue) {
                var value = modelValue || viewValue;
                if(!NAME_REG.test(value)){
                    return false;
                }
                return true;
            };
            // 异步验证
            ctrl.$asyncValidators.exist = function(modelValue, viewValue){
                var value = modelValue || viewValue;
                var deferred = $q.defer();
                $http.get(‘api/users/‘ + value).then(function(res) {
                    if(res.data.isExist){
                        deferred.reject(false);
                    }
                    deferred.resolve(true);
                })
                return deferred.promise;
            }
        }
    }
}

主页面:

<form name="myForm">
    <div class="form-group">
        <input type="text" name="username" ng-model="username" class="form-control" name-check minlength="2" required>
        <span ng-messages="myForm.username.$error" ng-messages-include="error.html" ng-show="myForm.username.$touched">
        </span>
    </div>
</form>

错误信息页面:

<span ng-message="required">必填</span>
<span ng-message="char">非法字符</span>
<span ng-message="minlength">太短了</span>
<span ng-message="exist">名称已存在</span>

ngMessages

ng-messages 是 AngularJS 1.3 提供的一个用来增强模版显示的模块,主要用在处理复杂的错误信息。

在以前的版本中,如果想处理错误信息的显示,可能需要定义一堆 code 再结合复杂的 ng-if 语句来实现。而且在输入同时满足多条错误规则的情况下,无法控制错误信息显示的优先级。这些,使用 ng-messages 可以完美解决。

准备工作

  1. 引入 angular-messages.js
  2. 添加依赖:angular.module(‘app‘, [‘ngMessages‘])

使用方法

有两种使用方法,一是将 ng-messages 当作属性指令使用:

<form name="myForm">
    <input type="text" ng-model="field" name="myField" required minlength="5" />
    <div ng-messages="myForm.myField.$error">
        <div ng-message="required">必填</div>
        <div ng-message="minlength">长度不够</div>
    </div>
</form>

这样会按照各个错误信息书写的先后顺序进行单一显示,如果想同时显示所有的错误信息,加个 ng-messages-multiple

<div ng-messages="myForm.myField.$error" ng-messages-multiple></div>

另一种是将 ng-messages 当作元素指令使用:

<ng-messages for="myForm.myField.$error">
    <ng-message when="required">必填</ng-message>
    <ng-message when="minlength">长度不够</ng-message>
</ng-messages>

如果很多表单项的错误提示信息都一样,也可以把错误信息放在模版里,使用 ng-messages-include 指令来引用:

<div ng-messages="myForm.username.$error" ng-messages-include="validateTemplate/error.html">
</div>

错误模版文件:

<div ng-message="required">必填</div>
<div ng-message="minlength">长度不够</div>

更详细的使用办法直接看 angular-messages.js 源文件里面的注释即可。

时间: 2024-08-04 21:54:23

Angular表单验证的相关文章

angular表单验证实例----可用的代码

前段时间,公司做一个单页面,就是一个表单验证,早开始在菜鸟教程上关注了angular,所以下派上用场了 angular里面对于表单验证,设置了很多指令. 也就是说不用自己写一些逻辑,直接绑定指令就行. ng-app     启动你angular的模块 ng-controller 控制器,启动你angualr里面的逻辑代码作用在页面上 ng-options  循环你select里面的option标签,很好用的 ng-submit,表单提交执行的 novalidate  表单form配合后期检测的

简话Angular 05 Angular表单验证

一句话: 可以使用所有html5表单验证功能,同时Angular还增强了部分验证,支持动态验证 1. 上源码 1 <div ng-controller="ExampleController"> 2 <form action="" name="exampleForm"> 3 <label>姓名(required ng-minlength=1 ng-maxlength=3): </label> <

简单的angular表单验证指令

<html ng-app="myApp"> <head> <meta charset="UTF-8"> <title>test表单验证</title> <script type="text/javascript" src="lib/angular/angular.js"></script> <script type="text/

从浅入深剖析angular表单验证

最近手上维护的组件剩下的BUG都是表单验证,而且公司的表单验证那块代码经历的几代人,里面的逻辑开始变得不清晰,而且代码结构不是很angular. 是很有必要深入了解表单验证. <body ng-controller="MainController"> <form name="form" novalidate="novalidate"> <input name="text" type="e

ngVerify - 更高效的 angular 表单验证

ngVerify v1.5.0 a easy Angular Form Validation plugin.简洁高效的__angular表单验证插件__ See how powerful it.看看它有多强大 动态校验 自动关联提交按钮 多种 tip 校验消息提示 不只校验 dom 元素值,还可以校验 ngModel 数据模型 支持任意类型表单元素,甚至可以校验非表单元素 提供 type 类型校验模板,你几乎不需要定校验规则 提供自定义规则 支持第三方组件校验 Show HOME - 首页 DE

angular js h5关于表单验证的例子

angular js表单验证 <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title></title> <script src="angular.min.js"></script> <link rel="stylesheet" href="

angular js 表单验证

1 <!doctype html> 2 <html ng-app="myapp"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 body{ 8 padding: 50px; 9 font-family: "微软雅黑"; 10 } 11 input{ 12 margi

基于angular的表单验证实例

最近,在学习angular下面就和大家分享一个简单的表单验证实例 在分享实例之前先整理一下,一些基础知识 input元素上使用的所有验证选项: 1必填项  <input type="text"  required/> 2最小长度 <input type="text" ng-minlength="5"/> 3最大长度 <input type="text" ng-maxlength="20&

angular之表单验证ngMessages

刚接触angular1.x很多经常用到的ngMessages的地方,这里顺便记一下,效果如下图: 如果引用了angular-messages.js报如下错误,说明你的angular.js和angular-messages.js版本不匹配,需要找到能用的版本. 可在这里在线测试各个版本https://docs.angularjs.org/api/ngMessages 引入版本匹配的angular-mseeages.js后,接下来开始使用它提供的表单验证提示吧... 最简单的就是将提示内容直接写在当