- 
     ng-form
 
 ng-form是Angular提供的directive。ng-form指令为form增补了一些额外特性。 它会控制那些带有ng-model指令和name属性的元素,监听他们的属性(包括其有效性)。
<ng-form name="demoForm">
    <input name=“name” type="text" required ng-model=“name”/>
    <input name=“password” type="text" minlength=“8” ng-model=“password”/>
    <button ng-disabled="demoForm.$invalid">Save</button>
</ng-form>ng-form指令实例化了名为”demoForm”的表单控制器(formcontroller)并且插入到当前的$scope中。每当表单控件中的值发生变化时,Angular 就会进行验证,并生成一个验证错误的列表(对应着INVALID状态)或者null(对应着VALID状态)。它还有自己的valid属性,这个属性只有在它包含的每个控件都有效时才是真。
    2.1 ng-form表单校验实现原理
    
    1)通过ng-model指令跟踪修改状态与有效性验证,
    
    状态:控件被访问过(ng-touched、ng-untouched)
    
    控件的值变化了(ng-dirty、ng-pristine)
    
    控件的值有效(ng-valid、ng-invalid)
    
    有效性:通过将验证器(validator)添加到表单控件上、一旦控件发生变化Angular就会调用验证器
    
    2)表单中控件的formcontroller实例(持有ng-model属性)会将自身注册到ng-form指令的formcontroller上,控件的name属性作为注册的键值;
   
    2.2 ng-model与验证器
    
    1)在控件上添加验证器会将验证器注册到控件控制器的validators中,会在
    
    调用ng-model时触发:
   
function processSyncValidators() {
  var syncValidatorsValid = true;
  forEach(ctrl.$validators, function(validator, name) {
    var result = validator(modelValue, viewValue);
    syncValidatorsValid = syncValidatorsValid && result;
    setValidity(name, result);
  });
  if (!syncValidatorsValid) {
    forEach(ctrl.$asyncValidators, function(v, name) {
      setValidity(name, null);
    });
    return false;
  }
  return true;
}
    2)angular自带验证器指令
    
    指令 说明
    
    required、ng-required 必须有输入
    
    pattern、ng-pattern 正则或函数进行校验
    
    minlength、ng-minlength 最小长度控制
    
    maxlength、ng-maxlength 最大长度控制
   
    四个验证器指令的实现细节基本上是一模一样的:
    
    1、设置controller的校验回调函数(验证器)。
    
    2、监控对应的属性,如果数据发生变化,就调用model controller的$validate进行有效性校验。
    
    以required为例:
   
ctrl.$validators.required = function(modelValue, viewValue) {
  return !attr.required || !ctrl.$isEmpty(viewValue);
};
attr.$observe('required', function() {
  ctrl.$validate();
});3)自定义验证器(验证当前名字是否被注册)
angular.module("demo").directive("nameRequired",function(){
    function link(controller) {
        var hasRegisteredName = ["张三","李四"];
        controller.$validators["namerequired"] = function (modelValue, viewValue) {
        var value = modelValue || viewValue;
        if(value){
            return hasRegisteredName.indexOf(value) < 0;
        }
        return true;
}
        }
return{
    “restrict”:”A”,(限制为属性级别)
    "require":"ngModel",
}
});
    3.控件状态CSS类
    
    • .ng-valid
    
    • .ng-invalid
    
    • .ng-pending
    
    • .ng-pristine
    
    • .ng-dirty
    
    • .ng-untouched
    
    • .ng-touched
    
    控件值无效且控件被访问过控件边框变色
   
.ng-invalid .ng-touched{
border-color: red;
} 
