使用AngularJS进行异步验证

时间:2015-12-16 16:26:55

标签: angularjs asp.net-mvc validation

有几件事情出了问题。首先,如何捕获模板中的错误,因为has-error类未应用,即使响应为404并且执行了正确的代码。

其次,这只适用于第一次。如果我离开该字段然后再次输入,每次按下一个键我都会得到一个TypeError: validator is not a function异常(正如您在代码中看到的那样,我只在blur上执行此操作)。我哪里错了?

服务电话

this.CheckIfUnique = function(code) {
    var deferred = $q.defer();
    $http.get("/Api/Codes/Unique/" + code).then(function() {
            deferred.resolve();
        }, function() {
            deferred.reject();
        });
        return deferred.promise;
    };

指令

var uniqueCode = [ "CodeService", function(codeService) {
    return {
        restrict: "A",
        require: "ngModel",
        link: function(scope, element, attrs, ctrl) {
            element.bind("blur", function(e) {
                if (!ctrl || !element.val()) return;
                var currentValue = element.val();
                ctrl.$asyncValidators.uniqueCode = codeService.CheckIfUnique (currentValue);
            });
        }
    };
}];
codeModule.directive("uniqueCode",uniqueCode);

HTML

<div class="form-group" ng-class="{'has-error' : ( codeForm.submitted && codeForm.code.$invalid ) || ( codeForm.code.$touched && codeForm.code.$invalid ) }">
    <label class="col-md-4 control-label" for="code">Code</label>
    <div class="col-md-8">
        <input class="form-control" id="code" name="code" ng-model="newCode.code" ng-required="true" type="text" unique-code />
        <span class="help-block" ng-show="( codeForm.submitted && codeForm.code.$error.required ) || ( codeForm.code.$touched && codeForm.code.$error.required)">Please enter a code</span>
        <span class="help-block" ng-show="codeForm.code.$pending.code">Checking if the code is available</span>
        <span class="help-block" ng-show="( codeForm.submitted && codeForm.code.$error.uniqueCode ) || ( codeForm.code.$touched && codeForm.code.$error.uniqueCode)">This code already exist</span>
    </div>
</div>

MVC控制器

public async Task<ActionResult> Unique(string code)
{
    if (string.IsNullOrWhiteSpace(code))
    {
        return new HttpStatusCodeResult(HttpStatusCode.NotFound);
    }
    return _db.Codes.Any(x => x.Code = code)
        ? new HttpStatusCodeResult(HttpStatusCode.NotFound)
        : new HttpStatusCodeResult(HttpStatusCode.Accepted);
}

修改

只是为了澄清,只有当我离开字段时才会调用API,异常会在按键时抛出(仅在我第一次离开字段后)

编辑2:

如果有人错过了评论,dfsq的答案会有效,如果您将ng-model-options="{ updateOn: 'blur' }"添加到输入中,它只会在blur上验证。

2 个答案:

答案 0 :(得分:1)

您未提供正确的验证程序功能。它应该使用匿名函数来返回promise对象(来自你的服务)。您也不需要模糊事件:

var uniqueCode = ["CodeService", function(codeService) {
    return {
        restrict: "A",
        require: "ngModel",
        link: function(scope, element, attrs, ctrl) {            
            ctrl.$asyncValidators.uniqueCode = function(value) {
                return codeService.CheckIfUnique(value);
            };
        }
    };
}];
codeModule.directive("uniqueCode", uniqueCode);

此外,您应该清理服务方法以不使用冗余的延迟对象:

this.CheckIfUnique = function(code) {
    return $http.get("/Api/Codes/Unique/" + code);
};

答案 1 :(得分:0)

关于问题的其他部分,邮件未显示,因为: 对于&#34;检查代码&#34;如果您有codeForm.code.$pending.code,则该邮件应为codeForm.code.$pending.uniqueCode

以下是plunker的工作: http://plnkr.co/edit/FH8GBhOipgvvUzrFYlwx?p=preview