4

初识angular


使用angular至今已经一年有余。从当初的不理解它的运行模式到现在的熟练使用,其中的曲折也就不再多说了。
写这篇文章的目的呢,是为了自己总结也让喜欢angular的同学对表单验证这块有个了解。

angular的重点难点


在angular里面比较关键的也是比较难理解的几个点是。
1:指令
2:服务

对于这两个点的话。如果有时间的话我也会写一篇内容来说明下。但之前看到有同学已经写过了这方面的内容,而且解释的挺清楚。所以在这也就不再重复了。详情参见[AngularJs学习笔记-第一章-指令(1)](http://segmentfault.com/a/1190000002988243),本文的重点也不在这里。之说以要说这个是因为在后面的内容里会涉及一些指令和服务。对于指令服务不清楚的同学请查看[官方文档的说明]。(http://docs.angularjs.cn/api/ng/directive)(查看官方文档需要翻墙这里给出angular中文社区里面的文档)。

angular表单验证


在日常开发中我们表单验证是我们必须面对的问题之前。在使用angular之前,做表单验证的话一般自己来封装一些公用的js库,或者使用jquery.validate这样的第三方库来实现。那么在angular里是如果做表单验证的呢?
angular的表单验证,能够将H5表单验证的功能和自己的验证指令结合起来进行使用,并且非常方便。
在angular中提供了很多表单验证的指令,我会介绍其中最常用也最核心的几个。讲完这些后我会介绍下如何创建自定义的验证指令。

<form name="form" novaildate>
<label name="email">你的邮箱</label>
<input type="email" name="email" ng-model="email" placeholder="输入邮箱"/>
</form>

如果要使用angular的表单验证,首先要确保表单必须要有一个name的属性
所有的输入字段都可以进行基本验证,比如最大,最小长度等。这些功能都由H5的表单属性提供,如果想要屏蔽浏览器对于表单默认的验证行为,可以在表单上添加novaildate的标记。

1.必填项


验证表单输入是否已经添加 之前在dom元素上加上required标记即可
    <input type="text" required/>

2.最小长度


验证表单输入的文本是否大于某个最小值,可以在输入的字段上使用指令 ng-minlength="{number}"
    <input type="text" ng-minlength="5"/>

3.最大长度


验证表单输入的文本是否大于或者等于某个最大值,可以使用指定ng-maxlength="{number}"
    <input type="text" ng-maxlength="5"/>

4.匹配模式


使用ng-pattern="/PATTERN/"来确保输入能匹配指定的正则表达式
    <input type="text" ng-pattern="[a-zA-Z]"/>

5.电子邮件


验证输入的文本是否是电子邮箱可以使用 type=email来实现
   <input type="email" name="email" ng-model="user.email" />

6.是否数字


验证输入的文本是否是为数字可以使用 type=number来实现
   <input type="number" name="age" ng-model="user.age" />

7.URL


验证输入的文本是否是为url可以使用 type=url来实现
    <input type="url" name="homepage" ng-model="user.homepage" />

8.表单属性

以上就是常用的一些内置的指令,关于自定义的指令,我会在后面的文章里来说明。下面继续说下在表单验证中的控制变量。
表单的属性可以在所在作用域的$scope对象中访问到,而我们又可以访问$scope对象因为JavaScript可以间接地访问dom中的表单属性借助这些属性,我们可以对表单做出实时的响应(双向绑定)这些属性包括下面这些.(可以通过formName.inputfieldName.property这种格式来访问这些属性)

1:未修改的表单
这是一个布尔类型的属性,用来判断用户是否修改了表单,如果未修改,值为true否则为false
formName.inputfieldName.$pristine
2:修改过的表单
只要用户修改过表单无论输入是否验证通过都返回true
formName.inputfieldName.$dirty
3:合法的表单
这个布尔属性用来判断表单的内容是否不合法,如果当前的表单内容是合法的。该属性就返回为true
formName.inputfieldName.$valid
4:不合法的表单
这个布尔属性用来判断表单的内容是否不合法,如果当前的表单内容是不合法的,该属性就返回为true
formName.inputfieldName.$invalid
5:错误
这是angular提交的另一个非常有用的属性:$error对象,她包含当前表单所有的验证内容。以及它们是否合法的信息,可以这样来访问formName.inputfieldName.$error,如果验证失败这个属性值为true,如果值为false说明通过了验证。

关于错误提示的一些样式


angular处理表单时,会根据表单当前的状态添加一些css样式,包括验证失败,验证成功等等,这些样式和之前的属性也类型。如下

.ng-pristine{}
.ng-dirty{}
.ng-valid{}
.ng-invalid{}
这个样式对于这个不同的表单状态比如当输入的字段非法时,.ng-invlid这个样式会被加到这个字段上。这样我们就可以根据自己的需求,来更改这些样式。 

话说了这多。代码怎么写呢下面呢,我来通过一个表单注册的例子来整体回顾下上面的内容

<!doctype html>
<html ng-app="myApp">
<head>
  <link rel="stylesheet" href="http://cdn.jsdelivr.net/foundation/4.3.2/css/foundation.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.js"></script>
</head>
<body>
  
<form name="signup_form" novalidate ng-submit="signupForm()">
  <fieldset>
    <legend>Signup</legend>
    
    <div class="row">
      <div class="large-12 columns">
        <label>Your name</label>
        <input type="text" 
            placeholder="Name" 
            name="name" 
            ng-model="signup.name" 
            ng-minlength=3 
            ng-maxlength=20 required />
       <div class="error" 
            ng-show="signup_form.name.$dirty && signup_form.name.$invalid">
        <small class="error" 
            ng-show="signup_form.name.$error.required">
            Your name is required.
        </small>
        <small class="error" 
                ng-show="signup_form.name.$error.minlength">
                Your name is required to be at least 3 characters
        </small>
        <small class="error" 
                ng-show="signup_form.name.$error.maxlength">
                Your name cannot be longer than 20 characters
        </small>
      </div>
      </div>
    </div>
      
    <div class="row">          
      <div class="large-12 columns">
        <label>Your email</label>
        <input type="email" 
          placeholder="Email" 
          name="email" 
          ng-model="signup.email" 
          ng-minlength=3 ng-maxlength=20 required />
        <div class="error" 
             ng-show="signup_form.email.$dirty && signup_form.email.$invalid">
          <small class="error" 
                 ng-show="signup_form.email.$error.required">
                 Your email is required.
          </small>
          <small class="error" 
                 ng-show="signup_form.email.$error.minlength">
                  Your email is required to be at least 3 characters
          </small>
          <small class="error" 
                 ng-show="signup_form.email.$error.email">
                 That is not a valid email. Please input a valid email.
          </small>
          <small class="error" 
                 ng-show="signup_form.email.$error.maxlength">
                  Your email cannot be longer than 20 characters
          </small>
        </div>
      </div>
    </div>
      
    <div class="large-12 columns">
      <label>Username</label>
        <input  type="text" 
                placeholder="Desired username" 
                name="username" 
                ng-model="signup.username" 
                ng-minlength=3 
                ng-maxlength=20 
                ensure-unique="username" required />
      <div class="error" ng-show="signup_form.username.$dirty && signup_form.username.$invalid">
        <small class="error" ng-show="signup_form.username.$error.required">Please input a username</small>
        <small class="error" ng-show="signup_form.username.$error.minlength">Your username is required to be at least 3 characters</small>
        <small class="error" ng-show="signup_form.username.$error.maxlength">Your username cannot be longer than 20 characters</small>
        <small class="error" ng-show="signup_form.username.$error.unique">That username is taken, please try another</small>
      </div>
    </div>  

    <button type="submit" ng-disabled="signup_form.$invalid" class="button radius">Submit</button>
  </fieldset>
</form>
  
<script>
angular.module('myApp', [])
.directive('ensureUnique', ['$http', function($http) {
  return {
    require: 'ngModel',
    link: function(scope, ele, attrs, c) {
      scope.$watch(attrs.ngModel, function() {
        $http({
          method: 'POST',
          url: '/api/check/' + attrs.ensureUnique,
          data: {'field': attrs.ensureUnique}
        }).success(function(data, status, headers, cfg) {
          c.$setValidity('unique', data.isUnique);
        }).error(function(data, status, headers, cfg) {
          c.$setValidity('unique', false);
        });
      });
    }
  };
}]);
</script>

</body>
</html>

在线的代码示例地址是:http://jsbin.com/epomuni/5/edit
下面我来讲解下这个表单的代码
这个表单的名字是signup_form 提交的表单时调用signupForm()在表单中我添加了一些验证,验证要求name字段最小的长度是3个字符,最大长度是20个字符等等。在下面的div里面我们通过ng-show指令结合表单的验证属性来动态的显示错误信息。在验证用户名的时候我通过了创建了一个自定义的指令,来通过异步请求来查询用户名是否合法
这里先给出代码。至于代码的详细含义。我会在后续的文章中给出说明。
上面的所有验证都是在用户输入的时候直接提示错误的。如果我们不想这么做。只想在用户提交的时候来显示错误信息
要如何来处理呢。也简单。把上面的代码稍作修改

<!doctype html>
<html ng-app="myApp">
<head>
  <link rel="stylesheet" href="http://cdn.jsdelivr.net/foundation/4.3.2/css/foundation.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.js"></script>
</head>
<body>
  
<form name="signup_form" novalidate ng-submit="signupForm()" ng-controller="signupController">
  <fieldset>
    <legend>Signup</legend>

    <div class="row">
      <div class="large-12 columns">
        <label>Your name</label>
        <input type="text"
               placeholder="Name"
               name="name"
               ng-model="signup.name"
               ng-minlength=3
               ng-maxlength=20 required />
        <div class="error"
            ng-show="signup_form.name.$dirty && signup_form.name.$invalid && signup_form.submitted">
        <small class="error"
            ng-show="signup_form.name.$error.required">
               Your name is required.
        </small>
        <small class="error"
               ng-show="signup_form.name.$error.minlength">
               Your name is required to be at least 3 characters
        </small>
        <small class="error"
               ng-show="signup_form.name.$error.maxlength">
               Your name cannot be longer than 20 characters
        </small>
      </div>
      </div>
    </div>

    <div class="row">
      <div class="large-12 columns">
        <label>Your email</label>
        <input type="email"
          placeholder="Email"
          name="email"
          ng-model="signup.email"
          ng-minlength=3 ng-maxlength=20 required />
        <div class="error"
             ng-show="signup_form.name.$dirty && signup_form.name.$invalid && signup_form.submitted">
          <small class="error"
                 ng-show="signup_form.email.$error.required">
                 Your email is required.
          </small>
          <small class="error"
                 ng-show="signup_form.email.$error.minlength">
                 Your email is required to be at least 3 characters
          </small>
          <small class="error"
                 ng-show="signup_form.email.$error.email">
                 That is not a valid email. Please input a valid email.
          </small>
          <small class="error"
                 ng-show="signup_form.email.$error.maxlength">
                 Your email cannot be longer than 20 characters
          </small>
        </div>
      </div>
    </div>

    <div class="large-12 columns">
      <label>Username</label>
        <input  type="text"
                placeholder="Desired username"
                name="username"
                ng-model="signup.username"
                ng-minlength=3
                ng-maxlength=20
                ensure-unique="username" required />
      <div class="error"
           ng-show="signup_form.name.$dirty && signup_form.name.$invalid && signup_form.submitted">
        <small class="error"
               ng-show="signup_form.username.$error.required">
               Please input a username
        </small>
        <small class="error"
               ng-show="signup_form.username.$error.minlength">
               Your username is required to be at least 3 characters
        </small>
        <small class="error"
               ng-show="signup_form.username.$error.maxlength">
               Your username cannot be longer than 20 characters
        </small>
        <small class="error"
               ng-show="signup_form.username.$error.unique">
               That username is taken, please try another
        </small>
      </div>
    </div>

    <button type="submit" class="button radius">Submit</button>
  </fieldset>
</form>
<script>
angular.module('myApp', [])
.directive('ensureUnique', ['$http', function($http) {
  return {
    require: 'ngModel',
    link: function(scope, ele, attrs, c) {
      scope.$watch(attrs.ngModel, function() {
        $http({
          method: 'POST',
          url: '/api/check/' + attrs.ensureUnique,
          data: {'field': attrs.ensureUnique}
        }).success(function(data, status, headers, cfg) {
          c.$setValidity('unique', data.isUnique);
        }).error(function(data, status, headers, cfg) {
          c.$setValidity('unique', false);
        });
      });
    }
  };
}])

.controller('signupController', ['$scope', function($scope) {
  $scope.submitted = false;
  $scope.signupForm = function() {
    if ($scope.signup_form.$valid) {
      // Submit as normal
    } else {
      $scope.signup_form.submitted = true;
    }
  }
}]);
</script>
</body>
</html>

现在仅当signup_form.submitted设置为true时,错误信息的div才会展示出来
关于angular表单验证这块暂时先讲到这里,后续的文章会继续来讲解angular表单验证的其他东西,包括最新的ng-message指定的使用。如果文章中有错误请大家指出来。有任何问题呢。请大家留言。欢迎吐槽。


jackwang
291 声望11 粉丝

一个乐观向上爱折腾各种技术的“拍黄片”程序员。