ngMessages(1.3+)
众所周知,表单和验证是Angular中复杂的组件之一。上面的例子不是特别好,不简洁。在Angular 1.3发布前,表单验证必须以这种方式编写。然而在发布的Angular 1.3中,Angular核心做了一个升级。它不再需要基于一个详细的表达式状态创建元素显示或隐藏(正如我们在本章所做的那样)。本质上这一功能会检查错误对象的状态发生了变化。此外,我们还得到了站点中每个表单需要的很多额外的和重复的标记。这显然不是一个理想的解决方案。从1.3开始,Angular中新增了一个ngMessages指令。安装安装ngMessages很简单,因为它被打包成了一个Angular模块。首先下载这个模块:$ bower install --save angular-messages或者,也可以从angular.org下载该文件并将它保存到项目中。还需要将angular-messages.js这个JavaScript引入我们的主HTML中:<script type="text/javascript" src="bower_components/angular-messages/angular-messages.js"></script>最后,我们还要告诉Angular将ngMessages作为应用程序的依赖模块引入,就像这样:angular.module('myApp', ['ngMessages']);现在,我们已经安装了ngMessages,然后可以马上开始使用它了。使用前面的例子作为基础,你可以移除ng-show指令,然后使用ngMessages的一个更简洁的实现替换它。
借助ngMessages,表本身比前面的实现更清洁,并且更好理解。
然而对于这个实现,一次只会显示一个错误消息。如果我们想要更新这个实现同时显示所有的错误将会怎样?很容易。只需在ng-message指令旁边使用ng-messages-multiple属性即可。sure you enter your nameYour name must be at least 3 charactersYour name cannot be longer than 20 characters
很多时候这些信息相互之间非常相似。我们可以将它们保存到模板中从而减少麻烦,而不是重新输入每个字段的错误信息。
This field is requiredThe field must be at least 3 charactersThe field cannot be longer than 20 characters
然后我们可以通过在视图中使用ng-messages-include属性引入这个模板来改进这个表单:
有时,你可能希望为不同的字段自定义错误信息。没问题,你可以在这个指令内简单地插入
一个自定义错误信息。由于ngMessages涉及ngMessages容器中错误列表的顺序,我们可以通过在这个指令中列出自定义错误信息的方式覆盖它们。此外,甚至还可以为自定义验证创建自定义消息。可以通过修改模型的$ parsers链做到这一点。例如,比方说我们想要创建一个自定义验证器验证用户名在一个注册表单中是否有效:
app.directive('ensureUnipue', function($http) {return {require: 'ngModel',link: function(scope, ele, attrs, ctrl) {ctrl.$parsers.push(function(val) {// 在这里添加验证});}}});
对于ngModel,你可以添加可以使用ngMessage指令显示/隐藏的自定义信息。还可以添加可
以使用ngMessage指令检查的带有自定义的消息的指令。例如,改变前面使用ngMessages的例子。在这中用法中,我们检查了错误信息的自定义属性。为了添加自定义错误消息,我们将会把它们应用到自定义ensureUnique指令的ngModel中。
app.directive('ensureUnique', function($http) {return {require: 'ngModel',link: function(scope, ele, attrs, ctrl) {var url = attrs.ensureUnique;ctrl.$parsers.push(function(val) {if (!val || val.length === 0) {return;}ngModel.$setValidity('checkingAvailability', true);ngModel.$setValidity('usernameAvailablity', false);$http({method: 'GET',url: url,params: {username: val}}).success(function() {ngModel.$setValidity('checkingAvailability', false);ngModel.$setValidity('usernameAvailablity', true);})['catch'](function() {ngModel.$setValidity('checkingAvailability', false);ngModel.$setValidity('usernameAvailablity', false);});return val;})}}});