2015-11-04 11 views
3

Я пытаюсь добавить поле проверки на один из моих входов, он должен запросить у сервера, действительно ли введенный номер НДС, поэтому я использую для этого асинхронный валидатор. Работает отлично с этим кодом:asyncValidator зависит от значения другого поля

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 обусловливающие значения другого поля (страна, более конкретно, является ли страна страной ЕС). Поле страны - это поле со списком, заполненное службой, в которой записаны все страны и их данные о ватах и ​​статус eu. Однако я не знаю, как ввести значение выбранной страны в заводскую функцию. Одна из идей заключалась в том, чтобы связать выбранную страну с ее собственным сервисом и использовать ее с завода, но затем проверка не запускается снова, когда выбрана другая страна. Если выбрана страна, не входящая в ЕС, мне все равно, что находится в поле.

ответ

3

Положительное значение в derective легко, вы можете передать его одному и тому же атрибуту или другому. Лучше не использовать изолированную область, потому что директива атрибута должна иметь возможность работать над каждым элементом. Таким образом, вы можете передать информацию о своей стране в директиву проверки, а затем передать ее функции, которая возвращается фабрикой.

Другая вещь - зависимость. Проверка выполняется только при изменении модели. Таким образом, вы должны разместить на нем часы/наблюдения.

Стоп говорить ... его код время ...

Здесь полностью работает пример на основе коды: 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); 
     }; 
    } 
    }; 
}); 

Ass вы можете увидеть у меня есть немного упростил асинхронный валидатор , но достаточно на данный момент. функция имеет два аргумента, поэтому я называю это из другой функции.

Директива используется так:

<input type="text" ng-model="vm.vat" name="vat" valid-vat="{{formModel.country}}" /> 

Так мы передаем значение модели прямо в атрибуте уважительной-чан. В директиве мы можем отправить значение в валидатор.

Затем мы должны наблюдать за содержанием валидатора и проверять запуск, если это было изменено с помощью $ validate().

Для этого случая, вероятно, достаточно, но если вы хотите передать модель напрямую, как: valid-vat = "formModel.country", это не сработает, потому что значение атрибута не изменяется. Таким образом, вы бы пошли в область или лучше оценили значение attr и наблюдали его изменения - как в этом примере: http://plnkr.co/edit/296x2shAVSe7FRv3mJnp?p=preview

+0

Большое спасибо. Решение было проще, чем я думал, я чувствую себя настолько глупо сейчас :), но эй научился новому. – Elvin

+0

Вам не нужно чувствовать себя глупо. Эта штука действительно немного сложна. Если вы углубляетесь и углубляетесь в проверки, они становятся все менее и менее прямолинейными. –

Смежные вопросы