2015-11-04 227 views
3

我想添加一個驗證字段給我的一個輸入,它應該請求服務器輸入的VAT號碼是否有效,所以我使用了一個異步驗證器。正常工作與此代碼: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檢查條件(國家,尤其是國別是否是歐盟國家)。 國家領域是一個組合框,通過一個服務,其中包含所有國家和他們的油缸信息和歐盟地位的記錄。 但是,我不知道如何將所選國家的價值注入工廠功能。其中一個想法是將選定的國家與自己的服務聯繫起來,並在工廠中使用它,但是當選擇另一個國家時,驗證不會再次運行。如果選擇一個非歐盟國家,我真的不在乎這個領域是什麼。

回答

3

將deasing的值放入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); 
     }; 
    } 
    }; 
}); 

屁股,你可以看到我有一點簡化異步驗證,但現在足夠了。函數有兩個參數,所以我從其他函數中調用它。

指令使用這樣的:

<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

你不必感到愚蠢。這件事真的有點棘手。如果你深入到驗證中,他們會變得越來越簡單。 –