$async 验证器 Angular
$asyncValidators Angular
我正在使用 Angular 1.3.* 并尝试验证我的表单。它在 ng-repeat 中。所以我可能会获得几个输入字段。我不仅要求该字段不为空,而且要求从后台取信息时要搜索成功。
我有这个输入框
<input type="text"
ng-model="user"
placeholder="username"
name="user{{$index}}"
typeahead="data as data.name for data in getUser($viewValue)"
typeahead-editable="false"
class="form-control"
autocomplete="off"
userValidator
required>
<div ng-if="myForm.$submitted" ng-messages="myForm.user{{$index}}.$error ">
<div ng-message="required">You need to type something</div>
</div>
<div ng-if="myForm.$submitted" ng-messages="myForm.user{{$index}}.$error">
<div ng-message="userValidator"> It seems that the entered user is not a valid input</div>
</div>
这是我对 backendCall 的尝试
.directive('userValidator',function($http,$q){
return{
require:'ngModel',
link:function($scope,element,attrs,ngModel){
ngModel.$asyncValidators.userAvailable=function(userInput){
return $http.post('/user'+userInput)
.then(function)????
}
}
}
});
请注意,我希望用户存在。我想我必须使用 asyncValidators 进行后端调用。但是,我似乎不明白。我要避免这种情况的一种方法是说,在除 "required" 之外的所有其他 $errors 上,显示消息 "It seems that the entered user is not a valid input"。我怎样才能成功进行后端调用并使用它,或者,我怎样才能确保在所有其他情况下显示其他错误消息?
如果用户名存在则直接 return true,如果不存在则直接拒绝并返回消息
.directive('userValidator',function($http,$q){
return{
require:'ngModel',
link:function($scope,element,attrs,ngModel){
ngModel.$asyncValidators.userAvailable = function(modelValue , viewValue) {
var userInput= modelValue || viewValue;
return $http.post('/user'+userInput)
.then(function() {
//username exists, this means validation success
return true;
}, function() {
//username does not exist, therefore this validation fails
return $q.reject('selected username does not exists');
});
}
}
}
});
一个 Firebase 示例:
.directive('isAccountNameAvailable',[ 'FireRef', '$q', function( FireRef, $q){
return {
require:'ngModel',
scope:{
profile:'=profile'
},
link:function($scope, element, attrs, ngModel){
ngModel.$asyncValidators.isAccountNameAvailable = function(modelValue , viewValue) {
var deferred = $q.defer();
var userInput = modelValue || viewValue;
$q.all([
FireRef.child('accountNames').child(userInput).once('value'),
FireRef.child('users').child($scope.profile.$id).child('accountName').once('value')
])
.then(function(snapshots){
/*
snapshots[0].val() is userID in accountNames path e.g accountNames/londonServicesLTD/userID
snapshots[0].key() is accountName key in accountNames e.g accountNames/londonServicesLTD
snapshots[1].val() is the current accountName value in user/userID/accountName e.g londonServicesLTD
snapshots[1].key() is 'accountName' key in user/userID/
*/
if(!snapshots[0].exists()){
deferred.resolve(true);
}else if(snapshots[0].val() === $scope.profile.$id){
deferred.resolve(true);
}else{
deferred.reject(false);
}
},function(){
deferred.reject(false);
});
return deferred.promise;
}
}
}
}])
html:
<div class="form-group" ng-class="{'has-success has-feedback': (forms.profileDetails.$submitted && forms.profileDetails.accountName.$valid),'has-error has-feedback': (forms.profileDetails.$submitted && forms.profileDetails.accountName.$invalid) }">
<label class="control-label">Account Name</label>
<input type="text" name="accountName" ng-model="model.accountName" required ng-trim no-special-chars camel-case is-account-name-available profile="profile" class="form-control" placeholder="E.g. londonServicesLTD">
<span ng-show="forms.profileDetails.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.profileDetails.accountName.$valid),'glyphicon-remove': ( forms.profileDetails.accountName.$invalid) }" aria-hidden="true"></span>
<div data-ng-messages="forms.profileDetails.$submitted && forms.profileDetails.accountName.$error" class="help-block">
<div data-ng-message="required">
- The <b>account name</b> is required.
</div>
<div data-ng-message="noSpecialChars">
- Not allowed to use special characters.
</div>
<div data-ng-message="isAccountNameAvailable">
- The account name is not available.
</div>
</div>
</div>
我正在使用 Angular 1.3.* 并尝试验证我的表单。它在 ng-repeat 中。所以我可能会获得几个输入字段。我不仅要求该字段不为空,而且要求从后台取信息时要搜索成功。
我有这个输入框
<input type="text"
ng-model="user"
placeholder="username"
name="user{{$index}}"
typeahead="data as data.name for data in getUser($viewValue)"
typeahead-editable="false"
class="form-control"
autocomplete="off"
userValidator
required>
<div ng-if="myForm.$submitted" ng-messages="myForm.user{{$index}}.$error ">
<div ng-message="required">You need to type something</div>
</div>
<div ng-if="myForm.$submitted" ng-messages="myForm.user{{$index}}.$error">
<div ng-message="userValidator"> It seems that the entered user is not a valid input</div>
</div>
这是我对 backendCall 的尝试
.directive('userValidator',function($http,$q){
return{
require:'ngModel',
link:function($scope,element,attrs,ngModel){
ngModel.$asyncValidators.userAvailable=function(userInput){
return $http.post('/user'+userInput)
.then(function)????
}
}
}
});
请注意,我希望用户存在。我想我必须使用 asyncValidators 进行后端调用。但是,我似乎不明白。我要避免这种情况的一种方法是说,在除 "required" 之外的所有其他 $errors 上,显示消息 "It seems that the entered user is not a valid input"。我怎样才能成功进行后端调用并使用它,或者,我怎样才能确保在所有其他情况下显示其他错误消息?
如果用户名存在则直接 return true,如果不存在则直接拒绝并返回消息
.directive('userValidator',function($http,$q){
return{
require:'ngModel',
link:function($scope,element,attrs,ngModel){
ngModel.$asyncValidators.userAvailable = function(modelValue , viewValue) {
var userInput= modelValue || viewValue;
return $http.post('/user'+userInput)
.then(function() {
//username exists, this means validation success
return true;
}, function() {
//username does not exist, therefore this validation fails
return $q.reject('selected username does not exists');
});
}
}
}
});
一个 Firebase 示例:
.directive('isAccountNameAvailable',[ 'FireRef', '$q', function( FireRef, $q){
return {
require:'ngModel',
scope:{
profile:'=profile'
},
link:function($scope, element, attrs, ngModel){
ngModel.$asyncValidators.isAccountNameAvailable = function(modelValue , viewValue) {
var deferred = $q.defer();
var userInput = modelValue || viewValue;
$q.all([
FireRef.child('accountNames').child(userInput).once('value'),
FireRef.child('users').child($scope.profile.$id).child('accountName').once('value')
])
.then(function(snapshots){
/*
snapshots[0].val() is userID in accountNames path e.g accountNames/londonServicesLTD/userID
snapshots[0].key() is accountName key in accountNames e.g accountNames/londonServicesLTD
snapshots[1].val() is the current accountName value in user/userID/accountName e.g londonServicesLTD
snapshots[1].key() is 'accountName' key in user/userID/
*/
if(!snapshots[0].exists()){
deferred.resolve(true);
}else if(snapshots[0].val() === $scope.profile.$id){
deferred.resolve(true);
}else{
deferred.reject(false);
}
},function(){
deferred.reject(false);
});
return deferred.promise;
}
}
}
}])
html:
<div class="form-group" ng-class="{'has-success has-feedback': (forms.profileDetails.$submitted && forms.profileDetails.accountName.$valid),'has-error has-feedback': (forms.profileDetails.$submitted && forms.profileDetails.accountName.$invalid) }">
<label class="control-label">Account Name</label>
<input type="text" name="accountName" ng-model="model.accountName" required ng-trim no-special-chars camel-case is-account-name-available profile="profile" class="form-control" placeholder="E.g. londonServicesLTD">
<span ng-show="forms.profileDetails.$submitted" class="glyphicon form-control-feedback" ng-class="{'glyphicon-ok': (forms.profileDetails.accountName.$valid),'glyphicon-remove': ( forms.profileDetails.accountName.$invalid) }" aria-hidden="true"></span>
<div data-ng-messages="forms.profileDetails.$submitted && forms.profileDetails.accountName.$error" class="help-block">
<div data-ng-message="required">
- The <b>account name</b> is required.
</div>
<div data-ng-message="noSpecialChars">
- Not allowed to use special characters.
</div>
<div data-ng-message="isAccountNameAvailable">
- The account name is not available.
</div>
</div>
</div>