Javascript AngularJS:试图立即验证的自定义验证器

Javascript AngularJS:试图立即验证的自定义验证器,javascript,angularjs,Javascript,Angularjs,我有一个表单,其中一些输入通过指令连接到自定义验证器。输入应该在blur上进行验证,并通过异步restapi调用进行验证 HTML: 上面的代码工作得很好,但请注意验证函数签名正下方的粗线条: 如果(!modelVal&&!viewVal)返回$q.defer().promise 如果没有该行,Angular会尝试在应用程序加载时立即验证字段,而不是仅在模糊时验证。这是一个问题,因为实际的验证代码执行一些字符串解析,并且由于modelVal和viewVal都是未定义的,JavaScript会抛出

我有一个表单,其中一些输入通过指令连接到自定义验证器。输入应该在blur上进行验证,并通过异步restapi调用进行验证

HTML:

上面的代码工作得很好,但请注意验证函数签名正下方的粗线条:

如果(!modelVal&&!viewVal)返回$q.defer().promise

如果没有该行,Angular会尝试在应用程序加载时立即验证字段,而不是仅在模糊时验证。这是一个问题,因为实际的验证代码执行一些字符串解析,并且由于
modelVal
viewVal
都是
未定义的
,JavaScript会抛出一个错误


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

Angular在每个属性的信号期间执行$validate。$观察输入验证指令,如ngPattern。您可以在patternDirective函数中看到这一点

我一直在试图找到一种方法来解决这个问题,因为我使用了许多输入验证(模式、最大长度、必需等),并且我的$AsyncValidator在加载期间触发了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;
    };
    
希望这对我有所帮助,因为我正在同一条船上寻找解决方案

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();
    };
  }
};
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;
};