2014-10-27 69 views
2

我有一个窗体,其中一些输入通过一个指令连接到自定义验证程序。输入应该在模糊时进行验证,并通过异步REST API调用完成。AngularJS:尝试立即验证的自定义验证程序

HTML:

<input type="text" 
    validate-this 
    ng-model="thisField" 
    ng-model-options="{'updateOn': 'blur'}" 
    ng-pattern="some pattern" 
/> 

指令(缩短为了简洁):

return { 
    access: 'A', 
    require: 'ngModel', 
    scope: false, 
    link: function (scope, elem, attrs, ngModel) { 
    ngModel.$asyncValidators.validateThis = function (modelVal, viewVal) { 
     if (!modelVal && !viewVal) return $q.defer().promise; 

     // returns a promise from the api service 
     return api.doSomeValidation(); 
    }; 
    } 
}; 

上面的代码完美地工作,但是请注意正下方的验证函数签名的hackish行:

没有那条线,尝试在应用程序加载时立即验证字段,而不是仅在模糊时验证字段。这是一个问题,因为实际验证代码会执行一些字符串分析,并且由于modelValviewVal都是undefined,JavaScript会引发错误。

我曾尝试禁用应用程序加载时将数据加载到字段中的功能,并且错误仍然发生。 ng-pattern中指定的模式,但是,确实尊重我的意愿,只验证字段模糊 - 它不会尝试验证页面加载。有没有什么办法告诉Angular 只有验证模糊,或让它停止尝试验证一旦页面加载?或者我错误地使用了$asyncValidators

+0

[如何将自定义验证添加到AngularJS窗体?](https://stackoverflow.com/q/12581439/6521116) – 2017-11-14 08:22:06

回答

2

Angular在每个attr。$的信​​号期间执行$ validate输入验证指令,例如ngPattern。你可以在他们的PatternDirective函数中看到。

我一直在试图找到一种解决方法,因为我使用了许多输入验证(模式,最大长度,所需等),并且我的$ asyncValidators在加载期间触发了7次。这导致Web服务器针对每个触发器执行。

解决方案:

  • 缓存Web方法响应
  • 附上您的处理程序页面加载后(或有某种类型的标志)
  • 烤ngPattern测试到您的异步处理。我可能会用这个。

    ngModel.$asyncValidators.validateThis = function (modelVal, viewVal) { 
        var deferred = $q.defer(); 
    
        if (!modelVal && !viewVal) 
         deferred.resolve(); 
        else if (!myPattern.test(modelVal)) 
         deferred.reject(); 
        else 
         api.doSomeValidation(value).then(function (result) { 
          deferred.resolve(); 
         }, function (result) { 
          deferred.reject(); 
         }) 
    
        return deferred.promise; 
    }; 
    

希望这有助于为我在同一条船上寻找一个解决方案。