Angular表单验证,前面一篇博客已经提到过了,不过那个时候我还尚未入门。呵呵呵。下面几篇博客将将结合一个简单的实例,通过不同的方式展现angualr表单验证的强大功能;当然,在这个实例,必然会涉及angular强大指令系统,以及依赖注入,路由,服务,XHR等等。
首选这个实例是,模仿CSDN用户注册步骤来的;大致分为四个步骤,在这四个步骤,会涉及四个不同的表单;已经可能满足现实项目各种较为复杂的表单需求。一个一个来。
第一个表单是一个简单的用户注册信息,截图如下:
上一篇博客已经介绍了,表单input的所有验证选项,诸如required,minlength等等之类,这里就不介绍了;
这里介绍设计表单验证的一些CSS样式;angular处理表单时,会根据表单当前的状态添加一些CSS(合法,为填写过,不合法等);
包括:
.ng-invalid { xxx } .ng-dirty { xxx} .ng-pristine { xxx} .ng-valid { xxx } .ng-invalid-required { xx x} .ng-invalid-minlength { xx } .ng-valid-max-length { xxx} //注意:如果使用了,最好要添加一点样式,不然会报错的className null
他们对应着表单输入字段的特定状态,当某个字段输入非法时,对应的ng-invalid会被添加到这个字段上去。(字段失去焦点之后添加)
比如,本实例中,为了在invalid时,标红可以这样处理:
input.ng-invalid { border: 1px solidred; }
失去焦点之后,效果如下:
我们这里需要验证两次输入的密码是否一致,这里我借助了angular的指令实现该功能。
新增指令password-validator
具体实现如下:
formApp.directive("passwordValidator",[function() { return { restrict:"A", require:"ngModel", link:function(scope, elem, attrs, ctrl) { console.log(elem); elem.on('keyup', function () { var passwordValue = scope.firstform.password.$viewValue; scope.$apply(function () { var v = false; if (!passwordValue || passwordValue === "" ||elem.val().trim() === "") { v = true; } else { v = elem.val() === passwordValue; } ctrl.$setValidity('pwmatch', v); }); }); } }; }]);
通过自定义指令获取进行比较,然后设置ctrl.$setValidity('pwmatch',v);然后试图中firstform.confirmPassword.$error.pwmatch就可以实时获取比较的结果;给出提示。
Html中的相关代码如下:
<div class="item"> <label class="labelItem"> {{firstForm.confirmPasswordTitle}} </label> <input type="password"name="confirmPassword" ng-model="firstformData.confirmPassword" password-validator placeholder="请再次输入密码" required/> <span class="errorMsg"> <span ng-show="firstform.confirmPassword.$dirty &&firstform.confirmPassword.$invalid &&!firstform.confirmPassword.$focused"> <span ng-show="firstform.confirmPassword.$error.required">{{ErrorMsg.confirmPasswordRequired}}</span> <span ng-show="firstform.confirmPassword.$error.pwmatch">{{ErrorMsg.passwordNotEqual}}</span> </span> </span> </div>
如果,我们想要在所有输入都合法时,在进行下一步呢,其实,只需要给按钮设置一个ng-disabled属性,当为true时,才可以下一步的。
<input type="button"ng-click="firstNext()" ng-disabled="firstform.$invalid" value="{{common.next}}">
输入合法后点击下一步,就需要发一个ajax请求啦。这里我稍微封装了一个服务来提供这个发送ajax请求。
为了熟练掌握创建服务的几种方式,这里使用了provider方式。
formApp.provider("AjaxUtil", function() { //默认的私有变量 var myPath = "http://jxj.com"; var setPath = function(path) { //通过config改版默认的属性 myPath = url; }; this.$get = function($http) { var obj = {}; var parseParam = function(url, param) { var params = JSON.stringify(param); return url + "=" + params; }; obj.postData= function (url, param) { var postURL = url +".action" + "?" + parseParam(url, param); return$http({method:"POST", url:postURL}); }; obj.getData =function (url, param) { var postURL = url +".action" + "?" + parseParam(url, param); return $http({method:"GET", url:postURL}); }; return obj; } });
然后在controller中注入服务AjaxUtil就可以使用了;
下面就是下一步后发送请求,成功后,切换路由到,第二步,如下:
$scope.firstNext= function() { var data = $scope.firstformData; var resultData = {}; AjaxUtil.postData($scope.defaultArr[0],data).success(function(data, status) { var resultData = data.resultData; if ($scope.common.failure === resultData.result) { return; } $location.url("second"); //等同于window.location.href ="#/second"; progress.next("second"); })
最后要说一个回填功能;假如第二步发现邮箱写错了;需要回到,第一页但是,我们不想所有信息重新填;这里就要借助双向数据绑定功能实现;在点击上一步后,由于路由切换页面并没有刷新页面,$scope.firstformData借助双向数据绑定,回填即可。但是刷新页面就不行,以为页面重新加载了。
这里要特别注意几点:
(1)$scope.firstformData需要初始化一下:$scope.firstformData = {};
(2)要实现双向数据绑定,要使用ng-model比如ng-model="firstformData.username"
好了,这一篇就说到这,下一篇将介绍,表单验证的其他强大功能。