简体   繁体   中英

angular form validation inside callback function - angular 1.2.5

I'm working an application with indexedDb as storage. In one of the forms while checking for the existence of a key I'm facing a strange error. Below is my validation directive code

app.directive('ensureUnique',['abcService', function ($abcService){
return {
    require : 'ngModel',
    link : function(scope,elem,attr,ctrl) {
        scope.$watch(attr.ngModel, function(){
             var checkExpenseType = $abcService.checkExpenseType();
             var index = checkExpenseType.get(scope.newExpenseName );
             index.onsuccess = function (e) {
                var result = e.target.result;
                if(result) {
                    ctrl.$setValidity('exists', true);
                 }else{
                    ctrl.$setValidity('exists', false);
                 }
             };
             index.onerror = function(e) {
                // TODO
             };   
        });
    }, 
  }}
]);

While entering input text if the value matches the key in db for the first time proper error message is displayed. Upon next key press error vanishes which is the correct behavior but for subsequent keypresses error reappears even though key is not present in DB.

 For example if "Food"  is the key in DB
 Foo - No error
 Food - Error - Key exists
 Foods - No error
 Foodss - Error - key exists
 Foodsss - Error - key exists
 ...       

Since there is a min length criteria of 3 characters directive is not triggered till I enter 3 characters.

Please also let me know if I'm doing the validation in the intended way or a better way exists

Thanks in advance

I've forked your Fiddle and made some changes. http://jsfiddle.net/U9y3H/1 .

Firstly I've added a scope.$apply() since your validation is happening asynchronously and therfore outside of angular's digest cycle.

Secondly I've swapped $setValidity to false if a match is found, and true if a match isn't found. I believe this to be correct if you want to invalidate the field if an entry already exists.

if(result) {
    // If a match is found, mark the field as invalid.
    ctrl.$setValidity('exists', false); 
}else{
    // If a match is not found mark "exists" as valid.
    ctrl.$setValidity('exists', true);
}
// Apply the validation changes.
scope.$apply();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM