Angular 多个表单字段的异步验证
Angular async validation with multiple form fields
我有一个异步验证指令,它在什么时候工作正常,但它取决于两个字段来定义一个人是否存在(numId 和类型),代码如下:
app.directive('personaUnica', function($http, $q){
return{
require:'ngModel',
scope: {
tipo: "=personaUnica"
},
link: function(scope, element, attrs, ctrl){
ctrl.$asyncValidators.personaUnica = function(modelValue, viewValue){
if (ctrl.$isEmpty(modelValue)) {
// valido si es vacio
return $q.when();
}
var defer = $q.defer();
$http.get('/someRESTEndpoint/', {
params:{ identificacion: modelValue, tipo: scope.tipo }
}).then(function(respuesta){
//Person found, not valid
if( respuesta.data.elementoExiste ){
defer.reject('Persona existe.');
}
}, function(respuesta){
//Person not found, resolve promise
if(!respuesta.data.elementoExiste){
defer.resolve();
}
});
return defer.promise;
}
}
}
});
但我不知道如何在其他相关字段发生更改时进行相同的验证。
我在指令中读到了一些关于 require ^form 的内容,但有点迷路了。
我已尝试添加此代码块
scope.$watch('tipo', function(){
ctrl.$validate();
});
但是我得到了一个无限的 $digest 循环。
提前致谢。
你可以这样做:
$scope.$watch('tipo', function(newValue, oldValue, scope) {
if (newValue != oldValue) {
ctrl.$validate();
}
});
这样,每当您的 $scope.tipo.
上有新值时,就会调用 $scope.watch
原来我在 ctrl.$asyncValidators.numId 里面的错误位置使用 watch,它必须在外面。现在它按预期工作。
app.directive('numId', function($http, $q){
return {
restrict : 'A',
scope: {
tipo: "=numId"
},
require: 'ngModel',
link: function(scope, element, attrs, ctrl){
ctrl.$asyncValidators.numId = function(modelValue, viewValue){
if (ctrl.$isEmpty(modelValue) || ctrl.$isEmpty(scope.tipo)) {
// consider empty model valid
console.log('Not going yet..');
return $q.when();
}
var defer = $q.defer();
$http.get("/some-server/endpoint",{
params:{ identificacion: modelValue, tipo: scope.tipo }
}).then(function(res){
if( res.data.personaExiste){
console.log('exists, not valid')
defer.reject('exists, not valid');
}else if( !res.data.personaExiste ){
console.log('NOT exists, valid!')
defer.resolve();
}
}, function(){
defer.reject('Error...');
});
return defer.promise;
}
// Search when tipo is changed
scope.$watch('tipo', function(){
console.log('Tipo:' + scope.tipo)
ctrl.$validate();
});
}
}
});
和 html:
<div class="form-group">
<label>Numero identificacion</label>
<input type="text"
name="numId"
required
ng-model="busqueda.numId"
num-id="busqueda.tipoUsuario">
<pre class="well"> {{ frmBuscar.numId.$error }} </pre>
</div>
我有一个异步验证指令,它在什么时候工作正常,但它取决于两个字段来定义一个人是否存在(numId 和类型),代码如下:
app.directive('personaUnica', function($http, $q){
return{
require:'ngModel',
scope: {
tipo: "=personaUnica"
},
link: function(scope, element, attrs, ctrl){
ctrl.$asyncValidators.personaUnica = function(modelValue, viewValue){
if (ctrl.$isEmpty(modelValue)) {
// valido si es vacio
return $q.when();
}
var defer = $q.defer();
$http.get('/someRESTEndpoint/', {
params:{ identificacion: modelValue, tipo: scope.tipo }
}).then(function(respuesta){
//Person found, not valid
if( respuesta.data.elementoExiste ){
defer.reject('Persona existe.');
}
}, function(respuesta){
//Person not found, resolve promise
if(!respuesta.data.elementoExiste){
defer.resolve();
}
});
return defer.promise;
}
}
}
});
但我不知道如何在其他相关字段发生更改时进行相同的验证。
我在指令中读到了一些关于 require ^form 的内容,但有点迷路了。
我已尝试添加此代码块
scope.$watch('tipo', function(){
ctrl.$validate();
});
但是我得到了一个无限的 $digest 循环。
提前致谢。
你可以这样做:
$scope.$watch('tipo', function(newValue, oldValue, scope) {
if (newValue != oldValue) {
ctrl.$validate();
}
});
这样,每当您的 $scope.tipo.
上有新值时,就会调用 $scope.watch原来我在 ctrl.$asyncValidators.numId 里面的错误位置使用 watch,它必须在外面。现在它按预期工作。
app.directive('numId', function($http, $q){
return {
restrict : 'A',
scope: {
tipo: "=numId"
},
require: 'ngModel',
link: function(scope, element, attrs, ctrl){
ctrl.$asyncValidators.numId = function(modelValue, viewValue){
if (ctrl.$isEmpty(modelValue) || ctrl.$isEmpty(scope.tipo)) {
// consider empty model valid
console.log('Not going yet..');
return $q.when();
}
var defer = $q.defer();
$http.get("/some-server/endpoint",{
params:{ identificacion: modelValue, tipo: scope.tipo }
}).then(function(res){
if( res.data.personaExiste){
console.log('exists, not valid')
defer.reject('exists, not valid');
}else if( !res.data.personaExiste ){
console.log('NOT exists, valid!')
defer.resolve();
}
}, function(){
defer.reject('Error...');
});
return defer.promise;
}
// Search when tipo is changed
scope.$watch('tipo', function(){
console.log('Tipo:' + scope.tipo)
ctrl.$validate();
});
}
}
});
和 html:
<div class="form-group">
<label>Numero identificacion</label>
<input type="text"
name="numId"
required
ng-model="busqueda.numId"
num-id="busqueda.tipoUsuario">
<pre class="well"> {{ frmBuscar.numId.$error }} </pre>
</div>