原文:http://odetocode.com/blogs/scott/archive/2014/10/16/working-with-validators-and-messages-in-angularjs.aspx

---------------------------------------------------------------------------------------------------------------

In a previous post we looked at a custom validation directive to confirm a user’s password.

The bigger picture from the post was not about how to register a user for a website, but how to work with the new validation and validation message features introduced in Angular 1.3, which just fully released this week.

Before we take a step back and look in more detail at what’s new in 1.3, let’s review what stays the same when it comes to form validation.

Same Old Validation

Here are a few points about what has not changed with validation.

1. When you give a <form> a name, Angular will add a property with the same name to the current $scope.

2. All named inputs inside a named <form> will be added to the form’s named property in $scope.

3. Each form and input still have boolean properties to describe if the object is $pristine or $dirty, and $valid or $invalid.

4. Angular still adds CSS classes to each form and input describing the state of the object (ng-dirty, ng-pristine, ng-valid, ng-invalid).

5. There is still an $error property on each form and input. The $error property describes failed validations.

Thanks to the behavior described in the above points, you can have a relatively functional form just using the following markup:

<form name="profileForm"
      ng-submit="profile.submit(profileForm.$valid)"
      novalidate>
       
    <input type="number" name="favoriteNumber"
           ng-model="profile.number"
           required min="1" />
       
    <input type="submit" value="Save" />
       
</form>

.. and a little bit of CSS ..

.ng-invalid {
  border-color: red;
  border-width: 2px;
}

You can try the above code on Plunker.

The Emperor's  New Validations

Angular 1.3 introduces a number of new features for form validation, including a new approach to writing validation code, a new approach to showing validation error messages, and plenty of small enhancements. like adding ng-submitted as a class to a form after a submit event. To only show validation errors or color code erroneous inputs after the user presses the submit button now only requires a more specific selector in CSS.

form.ng-submitted .ng-invalid {
  border-color: red;
  border-width: 2px;
}

Try the updated plunk here.

What follows is some more detail about validation messages and the validation API.

ngMessages

One of the messier parts of forms with Angular was the display management of validation errors. The management usually involved ng-if or ng-show directives with ugly expressions like in the following code.

<input type="number" name="favoriteNumber"
       ng-model="profile.number"
       required min="1" />
 
<span ng-if="profileForm.favoriteNumber.$error.required">
    Required!
</span>

And this is only a single validation error for a single field. Once you added messages for each validation attribute in each input field, then added class names, there was quite a bit of markup.

ngMessages is a new module for Angular that your application can depend on after adding angular-message.js. Once in place, validation messages look like the following.

<input type="number" name="favoriteNumber"
       ng-model="profile.number"
       required min="1" />
<div ng-messages="profileForm.favoriteNumber.$error" class="errors">
    <span ng-message="required">Required!</span>
    <span ng-message="min">Too small!</span>
</div>

The ngMessages directive will watch the $error property of an input and toggle the first matching ngMessage directive in its messages collection.

Now we’ve gotten most of the uglier expressions out of the markup, but we can also define a template file for messages..

<span ng-message="required">Required!</span>
<span ng-message="min">Too small!</span>
<span ng-message="number">Must be a number!</span>
<span ng-message="odd">Odd numbers only!</span>
<!--  and so on, for all possible validation attributes -->

.. and include the template whenever we need to show error messages for a field.

<div ng-messages="profileForm.favoriteNumber.$error"
     ng-messages-include="messages.html"
     class="errors">
</div>

Now we’ve removed most of the unsightly and bulky markup from our forms. However, since error messages come from a template they are likely to be generic error messages like the ones in this example, messages like “Too small!”. There is no easy way to poke a field name or attribute value into a message, unfortunately, but there is the ability to override a message.

<div ng-messages="profileForm.favoriteNumber.$error"
     ng-messages-include="messages.html"
     class="errors">
            
     <!-- overrides the min message from the include -->
     <span ng-message="min">Must be more than 1</span>
</div>

This last bit of code added to the Plunker here.

$validators

Also new in 1.3 is the $validators object on the ngModel controller. Adding a property to this object effectively registers a new validation rule to an input using the name of the property. To get to the $validators property you’ll want to create a custom directive that requires the ngModel controller. The following code adds an “odd” validation rule that I can use to ensure that an input type=”number” will only accept odd numbers.

app.directive("odd", function() {
    return {
        restrict: "A",
         
        require: "ngModel",
         
        link: function(scope, element, attributes, ngModel) {
            ngModel.$validators.odd = function(modelValue) { 
                return modelValue % 2 === 1;
            }
        }
    };
});

Angular automatically invokes the odd function whenever the model value changes (you can also receive the view value as a second parameter)., All the validation function needs to do is return true or false – is the value valid? A return of false will mark the model as invalid and set a property on the associated $error object. To apply the validation rule use the directive on an element using ngModel.

<input type="number" name="favoriteNumber"
       ng-model="profile.number"
       required min="1" odd />

The associated ngMessage for the attribute will automatically appear when the validation rule fails.

<span ng-message="odd">Odd numbers only!</span>

An updated plunk using the above code lives here.

$asyncValidators

A validation rule added to a model’s $asyncValidator pipeline will typically be a validation rule that needs server-side logic to make a decision. Like everything and anything async in Angular, an async validator will return a promise. If the promise resolves, Angular considers the value valid. If the promise is rejected, the value is invalid.

Here is a prime number validation rule that simulates a slow server-side response using $timeout.

app.directive("prime", function($q, $timeout) {
 
    var isPrime = function(n) {
      if (n < 2) {
        return false;
      }
 
      for (var i = 2; i <= Math.sqrt(n); i++) {
        if (n % i == 0) {
          return false;
        }
      }
      return true;
    };
 
    return {
      restrict: "A",
      require: "ngModel",
      link: function(scope, element, attributes, ngModel) {
        ngModel.$asyncValidators.prime = function(modelValue) {
          var defer = $q.defer();
          $timeout(function(){
            if(isPrime(modelValue)) {
              defer.resolve();
            } else {
              defer.reject();
            }
          }, 2000);
          return defer.promise;
        }
      }
   };
});

Using an async validator is no more difficult than using a regular validator, all we need to do is add the directive to the input element.

<input type="number" name="favoriteNumber"
       ng-model="profile.number"
       required min="1" odd prime />
       
<div ng-if="profileForm.favoriteNumber.$pending">
     Calculating....
</div>

Notice you can give some visual clues a pending validation calculation by using the $pending flag provided by Angular.

Try this version of the code in this plunk.

Summary

The summary for this article is intentionally left blank. Like you were going to read it anyway…

Working with Validators and Messages in AngularJS的更多相关文章

  1. [AngularJS] AngularJS系列(3) 中级篇之表单验证

    目录 基本验证 验证插件messages 自定义验证 基本验证 <form name="form" novalidate ng-app> <span>{{f ...

  2. angularjs的表单验证

    angularjs内置了常用的表单验证指令,比如min,require等.下面是演示: <!DOCTYPE html> <html> <head> <meta ...

  3. 具备 jQuery 经验的人如何学习AngularJS(附:学习路径)

    这是一个来自stackoverflow的问答,三哥直接把最佳回答搬过来了. 都说AngularJS的学习曲线异常诡异~~~ Q: “Thinking in AngularJS” if I have a ...

  4. AngularJS笔记---路由视图

    最近有同事提到过关于ng-view的使用, 其实自己也不懂了,由于最近一直在做AngularJs的Rearch,所以就看了一些关于ng-view的国外博客. 做过ASP.NET MVC4的都知道, 我 ...

  5. jQuery和AngularJS的区别小分析

    最近一直在研究angularjs,最大的感受就是它和之前的jQuery以及基于jQuery的各种库设计理念完全不同,如果不能认识到这点而对于之前做jQuery开发的程序员,去直接学习angularjs ...

  6. angularJS和jQuery的区别

    问题: 假如我熟悉利用jQuery去开发客户端应用,那么我怎么上手angularjs,能否描述下所需要的模式转变,下面这些问题能够帮助你给出一个回答: 1.在设计客户端web应用的时候有什么区别,最大 ...

  7. 关于angularjS与jQuery框架的那些事

    这篇文章主要介绍了jQuery和angularJS的区别浅析,本文着重讲解一个熟悉jQuery的程序员如何应对angularJS中的一些编程思想的转变吗,需要的朋友可以参考下 最近一直研究angula ...

  8. AngularJS作出简单聊天机器人

    简单聊天机器人 很初级的对话框形式.以前做对话框使用js,今天尝试使用AngularJS做出来 这里直接使用自己写的JSON数据. <!DOCTYPE html> <html lan ...

  9. AngularJs 与Jquery的对比分析,超详细!

    闲来无事,在网上发现了一篇对比AngularJs和Jquery的文章.恰好最近自己也在研究AngularJs.特此收藏.需要的朋友可以参考. 原问题:假如我熟悉利用jQuery去开发客户端应用,那么我 ...

随机推荐

  1. exit - 使程序正常中止

    SYNOPSIS 总览 #include <stdlib.h> void exit(int status); DESCRIPTION 描述 函数 exit() 使得程序正常中止,statu ...

  2. environ - 用户环境(变量)

    SYNOPSIS 总览 extern char **environ; DESCRIPTION 描述 变量 environ 指向的是一个叫 'environment'(环境)的字符串数组 (这个变量必须 ...

  3. 光猫&路由器网络配置

    前期准备:电脑(工业电脑).网线.光猫.路由器 1.检查连接光猫后能否正常上网:把网线两头的水晶头,一头插在光猫上的千兆口,一头插在电脑(工业电脑)的网口上,看电脑能否正常上网: 可以正常上网:说明光 ...

  4. 第4节 hive调优:2、数据倾斜

    数据的倾斜: 主要就是合理的控制我们的map个数以及reduce个数 第一个问题:maptask的个数怎么定的???与我们文件的block块相关,默认一个block块就是对应一个maptask 第二个 ...

  5. mongodb windows 开机启动

    1)新建存放db E:\mongodb\data\db 2)新建日志文件 E:\mongodb\logs\log.txt 3)管理员运行Cmd 4)CD mongodb安装路径 5)运行命令 mong ...

  6. PyTorch的十七个损失函数

    本文截取自<PyTorch 模型训练实用教程>,获取全文pdf请点击: tensor-yu/PyTorch_Tutorial​github.com 版权声明:本文为博主原创文章,转载请附上 ...

  7. zabbix 3.4安装

    一.server安装 [root@zabbix ~]# cat /etc/redhat-release CentOS Linux release (Core) [root@zabbix ~]# una ...

  8. js实现复制粘贴功能

    在项目中使用到复制粘贴功能,虽然网上有很多大牛封装了很多的插件,但是还是想不去使用插件,就像自己来实现这个功能. 另一篇是禁止复制粘贴 前端er怎样操作剪切复制以及禁止复制+破解等 初步想法: 1. ...

  9. openmediavault 4.1.3 插件开发

    参考网址:https://forum.openmediavault.... 创建应用GUI 创建应用目录:/var/www/openmediavault/js/omv/module/admin/ser ...

  10. noi.ac NOIP2018 全国热身赛 第四场 T1 tree

    [题解] 考虑从小到大枚举边权,按顺序加边. 当前树被分成了若干个联通块,若各个块内的点只能跟块外的点匹配,那么最终的min g(i,pi)一定大于等于当前枚举的边. 判断各个联通块内的点是否全部能跟 ...