调用REST API的自定义指令验证程序设置表单太慢。$ invalid以防止表单提交

时间:2015-07-17 16:58:44

标签: angularjs angularjs-directive

我在输入文本字段上有一个自定义指令,它使用$ http(实际是Restful Resource)调用REST Web服务Api。此Web服务调用通常需要500毫秒,当呼叫返回时,用户可能已经点击表单的提交按钮并继续。

我怎么能真正阻止它?

输入字段:

<input type="text" data-my-user-input-validation="true" data-ng-model-options="{ updateOn: 'blur' }">

形式:

<form name="myform" role="form" data-ng-submit="myform.$valid && submit()" novalidate>

自定义指令:

app.directive('myUserInputValidation', function(UserInputRestrictionValidationPost) {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            var validate = attrs.myUserInputValidation;

            if (validate === 'false') {
                // false, don't need to do anything
                return;
            }

            function setAsInvalid(bool) {
                ngModel.$setValidity('userInputValidation', bool);
            }

            ngModel.$parsers.push(function(value) {
                if (!value || value.length == 0) return;

                UserInputRestrictionValidationPost.get({
                    value: value
                }, function(data) {
                    if (data.status === 'OK') {
                        // api return ok
                        setAsInvalid(true);

                    } else {
                        // failure or error
                        setAsInvalid(false);
                    }
                });

                return value;
            })
        }
    }
});

答案

app.directive('myUserInputValidation', function(UserInputRestrictionValidationPost) {
  return {
    require : 'ngModel',
    link : function(scope, element, attrs, ngModel) {
        var validate = attrs.myUserInputValidation;

        if(validate === 'false'){
            // false, don't need to do anything
            return;
        }

        function setAsInvalid(bool) {
            ngModel.$setValidity('userInputValidation', bool); 
        }

        ngModel.$asyncValidators[attrs.name] = function(modelValue, viewValue) {
            var value = modelValue || viewValue;

            if(!value || value.length == 0){
                setAsInvalid(true);
                return false;
            }

            return UserInputRestrictionValidationPost.get({ value: value }).$promise.then(function (data) {
                if(data.status === 'OK'){
                    // api ok
                    setAsInvalid(true);
                    return false;

                }else{
                    // failure or error
                    setAsInvalid(false);
                    return true;
                }
            });
        };
    }
  }
});

1 个答案:

答案 0 :(得分:1)

为此,存在异步验证器 - 请参阅ngModelController中的$ asyncValidators属性(https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

ngModel.$asyncValidators. userInputValidation = function(modelValue, viewValue) {
    if (!value || value.length == 0) {
      return;
    }

     return UserInputRestrictionValidationPost.getResultAsPromise(value);

小心返回值。你必须在这里回复承诺。