angularjs - asyncValidator 依赖于其他字段的值

标签 angularjs validation

我正在尝试将验证字段添加到我的输入之一,它应该请求服务器输入的增值税号是否有效,因此我为此使用了异步验证器。使用此代码可以正常工作:

myApp.factory('isValidVat', function($q, $http) {
  return function(vat) {
    var deferred = $q.defer();
    console.log(vat);
    $http.get('/api/vat/' + vat).then(function() {
      deferred.resolve();
    }, function() {
      deferred.reject();
    });

    return deferred.promise;
  }
});

myApp.directive('validVat', function(isValidVat) {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      ngModel.$asyncValidators.vat = isValidVat;
    }
  };
});
<form name="form" novalidate ng-submit="check(form)">
    <div class="vat-field">
        <label>VAT number
            <input type="text" ng-model="formModel.vat" name="vat" valid-vat="true">
        </label>
        <div ng-show="registerForm.$submitted || registerForm.vat.$touched">
            <span ng-show="registerForm.vat.$error.vat">
                <small class="error">Your VAT address is not valid, please correct.</small>
            </span>
        </div>
    </div>
    <div class="country-field">
        <label>Country
            <select ng-model="formModel.country" name="country">
                <option value="{{country.iso_3}}" ng-repeat="country in countries()">{{country.name}}</option>
            </select>
        </label>
    </div>
    <button type="submit">Check</button>
</form>


但是,我想让这个 asyncValidator 检查以另一个字段的值为条件(国家,更具体地说,该国家是否是欧盟国家)。
国家/地区字段是一个组合框,通过一项服务填充,该服务记录所有国家及其增值税信息和欧盟状态。
但是,我不知道如何将所选国家的值注入(inject)到工厂函数中。 One idea was to link the selected country to it's own service and use it from the factory, but then the validation doesn't run again when another country is selected.如果选择了一个非欧盟国家,我真的不在乎这个领域有什么。

最佳答案

将值传递给指令很容易,您可以将其传递给相同的属性或其他属性。最好不要使用孤立的范围,因为属性指令应该能够在每个元素上工作。因此,您可以将您的国家信息传递给验证指令,然后将其传递给工厂返回的函数。

另一件事是依赖。验证仅在模型本身更改时运行。因此,您必须对其进行观察/观察。

别再说了……它的代码时间……

这是基于您的代码的完整工作示例:
http://jsbin.com/yuqibajehe/edit?html,js,output

  .factory('isValidVat', function($q, $http, $timeout) {
    return function(vat, country) {
      var deferred = $q.defer();

      console.log(vat, country);

      $timeout(function() {
        if (vat === country) {
          deferred.resolve();
        } 

        deferred.reject();
      },1000);

      return deferred.promise;
    };
  })
    .directive('validVat', function(isValidVat) {
  return {
    restrict: 'A',
    require: 'ngModel',

    link: function(scope, element, attrs, ngModel) {

      attrs.$observe('validVat', function() {
        ngModel.$validate();
      });

      ngModel.$asyncValidators.vat = function(vat) {
        return isValidVat(vat, attrs.validVat);
      };
    }
  };
});

你可以看到我稍微简化了异步验证器,但现在已经足够了。函数有两个参数,所以我从其他函数调用它。

指令是这样使用的:
 <input type="text" ng-model="vm.vat" name="vat" valid-vat="{{formModel.country}}" />

所以我们将模型的值直接传递给属性valid-vat。
在指令中,我们可以将值发送到验证器。

然后我们必须观察验证器的内容,并在使用 $validate() 更改时运行验证。

对于这种情况,这可能就足够了,但是如果您想直接传递模型,例如:valid-vat="formModel.country"它将不起作用,因为属性的值不会改变。所以你应该去范围,或者更好地评估 attr 值并观察它的变化——就像在这个例子中:http://plnkr.co/edit/296x2shAVSe7FRv3mJnp?p=preview

关于angularjs - asyncValidator 依赖于其他字段的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33516608/

相关文章:

javascript - Angular 传递变量以包含文件

javascript - AngularJS 的 ng-table 重新加载不起作用

javascript - 如何删除 JQuery Multifile 中的警报验证

java - java中如何验证数据类型?

angularjs - UI GRID 垂直滚动速度极快的问题

javascript - 在angularjs中的ng-click函数中获取元素的属性

javascript - 为什么在添加常量或固定按钮时标题会下降。?

python - 如何在 Emacs 中检查 Python 代码的语法而不实际执行它?

javascript - HTML 验证/脚本 JS

javascript - 我想停止将非字母字符放入输入中