将自定义参数传递给$ asyncValidators

时间:2016-03-21 16:24:22

标签: angularjs angularjs-validation

我有一个指令,它是一个异步验证器:

// part of directive
return {
  restrict: 'A',
  scope: {
    edit: '=', 
  },
  require: 'ngModel',
  link: function(scope, element, attrs, ngModel) {

    // .bind because I am using es6 classes(so $http service is on `this`)
    ngModel.$asyncValidators.uniqueCode = Service.checkCode.bind(Service);
  }
};

我想将scope.edit传递给.checkCode方法(对后端进行http调用),并根据响应状态和该变量解析/拒绝承诺。

2 个答案:

答案 0 :(得分:0)

好的,事实证明我可以自己将值传递给服务方法:

ngModel.$asyncValidators.uniqueCode = function() {
  return Service.checkCode(ngModel.$viewValue, scope.edit);
};

答案 1 :(得分:0)

虽然您找到了答案,但我发布了一个使用您的测试用例的异步验证器的综合示例。

angular.module('myModule').directive('nameValidator', function($http, $q) {
    return {
        restrict: 'A',
        require: 'ngModel',
        scope: {
            edit: '=', 
        },
        link: function(scope, element, attrs, ngModel) {
            ngModel.$asyncValidators.uniqueCode = function() {
                return $http.post('/checkFunc', {name: scope.edit}).then(
                    function(response) {
                        if (!response.data.validUsername) {
                            //invalid case ..validation failed
                            return $q.reject(response.data.errorMessage);
                        }
                        return true;
                    }
                );
            };
        }
    };
});

要使用它 -

<input type="text" ng-model="username" required name-validator>

不使用直接范围的其他方法。

.directive('usernameValidator', function($q, $timeout) {
                    return {
                        require: 'ngModel',
                        link: function(scope, element, attrs, ngModel) {
                            ngModel.$asyncValidators.username = function(modelValue, viewValue) {
                                if (!viewValue) {
                                    return $q.when(true);
                                }
                                var deferred = $q.defer();
                                $timeout(function() {
                                    // Faking actual server-side validity check with $http.
                                    // Let's pretend our service is so popular all short username are already taken
                                    if (viewValue && viewValue.length < 5) {
                                        deferred.reject();
                                    }

                                    deferred.resolve();
                                }, 2000);
                                return deferred.promise;
                            };
                        }
                    };
                });